genetlink.c (175ae3ad59ab3459652bd2ae3bbc1785aeba1bf3) genetlink.c (d07dcf9aadd6b2842b439e8668ff7ea2873f28d7)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * NETLINK Generic Netlink Family
4 *
5 * Authors: Jamal Hadi Salim
6 * Thomas Graf <tgraf@suug.ch>
7 * Johannes Berg <johannes@sipsolutions.net>
8 */

--- 1029 unchanged lines hidden (view full) ---

1038 genlmsg_multicast_allns(&genl_ctrl, msg, 0,
1039 0, GFP_ATOMIC);
1040 rcu_read_unlock();
1041 }
1042
1043 return 0;
1044}
1045
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * NETLINK Generic Netlink Family
4 *
5 * Authors: Jamal Hadi Salim
6 * Thomas Graf <tgraf@suug.ch>
7 * Johannes Berg <johannes@sipsolutions.net>
8 */

--- 1029 unchanged lines hidden (view full) ---

1038 genlmsg_multicast_allns(&genl_ctrl, msg, 0,
1039 0, GFP_ATOMIC);
1040 rcu_read_unlock();
1041 }
1042
1043 return 0;
1044}
1045
1046static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
1047{
1048 const struct genl_family *rt;
1049 unsigned int fam_id = cb->args[0];
1050 int err;
1051
1052 if (!fam_id) {
1053 struct nlattr *tb[CTRL_ATTR_MAX + 1];
1054
1055 err = genlmsg_parse(cb->nlh, &genl_ctrl, tb,
1056 genl_ctrl.maxattr,
1057 genl_ctrl.policy, cb->extack);
1058 if (err)
1059 return err;
1060
1061 if (!tb[CTRL_ATTR_FAMILY_ID] && !tb[CTRL_ATTR_FAMILY_NAME])
1062 return -EINVAL;
1063
1064 if (tb[CTRL_ATTR_FAMILY_ID]) {
1065 fam_id = nla_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
1066 } else {
1067 rt = genl_family_find_byname(
1068 nla_data(tb[CTRL_ATTR_FAMILY_NAME]));
1069 if (!rt)
1070 return -ENOENT;
1071 fam_id = rt->id;
1072 }
1073 }
1074
1075 rt = genl_family_find_byid(fam_id);
1076 if (!rt)
1077 return -ENOENT;
1078
1079 if (!rt->policy)
1080 return -ENODATA;
1081
1082 err = netlink_policy_dump_start(rt->policy, rt->maxattr, &cb->args[1]);
1083 if (err)
1084 return err;
1085
1086 while (netlink_policy_dump_loop(&cb->args[1])) {
1087 void *hdr;
1088 struct nlattr *nest;
1089
1090 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
1091 cb->nlh->nlmsg_seq, &genl_ctrl,
1092 NLM_F_MULTI, CTRL_CMD_GETPOLICY);
1093 if (!hdr)
1094 goto nla_put_failure;
1095
1096 if (nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, rt->id))
1097 goto nla_put_failure;
1098
1099 nest = nla_nest_start(skb, CTRL_ATTR_POLICY);
1100 if (!nest)
1101 goto nla_put_failure;
1102
1103 if (netlink_policy_dump_write(skb, cb->args[1]))
1104 goto nla_put_failure;
1105
1106 nla_nest_end(skb, nest);
1107
1108 genlmsg_end(skb, hdr);
1109 continue;
1110
1111nla_put_failure:
1112 genlmsg_cancel(skb, hdr);
1113 break;
1114 }
1115
1116 cb->args[0] = fam_id;
1117 return skb->len;
1118}
1119
1046static const struct genl_ops genl_ctrl_ops[] = {
1047 {
1048 .cmd = CTRL_CMD_GETFAMILY,
1049 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1050 .doit = ctrl_getfamily,
1051 .dumpit = ctrl_dumpfamily,
1052 },
1120static const struct genl_ops genl_ctrl_ops[] = {
1121 {
1122 .cmd = CTRL_CMD_GETFAMILY,
1123 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1124 .doit = ctrl_getfamily,
1125 .dumpit = ctrl_dumpfamily,
1126 },
1127 {
1128 .cmd = CTRL_CMD_GETPOLICY,
1129 .dumpit = ctrl_dumppolicy,
1130 },
1053};
1054
1055static const struct genl_multicast_group genl_ctrl_groups[] = {
1056 { .name = "notify", },
1057};
1058
1059static struct genl_family genl_ctrl __ro_after_init = {
1060 .module = THIS_MODULE,

--- 175 unchanged lines hidden ---
1131};
1132
1133static const struct genl_multicast_group genl_ctrl_groups[] = {
1134 { .name = "notify", },
1135};
1136
1137static struct genl_family genl_ctrl __ro_after_init = {
1138 .module = THIS_MODULE,

--- 175 unchanged lines hidden ---