Skip to content

Commit b16fb41

Browse files
roopa-prabhudavem330
authored andcommitted
net: fib_rules: add extack support
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent f9d4b0c commit b16fb41

File tree

7 files changed

+63
-22
lines changed

7 files changed

+63
-22
lines changed

include/net/fib_rules.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ struct fib_rules_ops {
7575
int (*configure)(struct fib_rule *,
7676
struct sk_buff *,
7777
struct fib_rule_hdr *,
78-
struct nlattr **);
78+
struct nlattr **,
79+
struct netlink_ext_ack *);
7980
int (*delete)(struct fib_rule *);
8081
int (*compare)(struct fib_rule *,
8182
struct fib_rule_hdr *,

net/core/fib_rules.c

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -469,14 +469,18 @@ static int fib_nl2rule(struct sk_buff *skb, struct nlmsghdr *nlh,
469469
if (frh->src_len)
470470
if (!tb[FRA_SRC] ||
471471
frh->src_len > (ops->addr_size * 8) ||
472-
nla_len(tb[FRA_SRC]) != ops->addr_size)
472+
nla_len(tb[FRA_SRC]) != ops->addr_size) {
473+
NL_SET_ERR_MSG(extack, "Invalid source address");
473474
goto errout;
475+
}
474476

475477
if (frh->dst_len)
476478
if (!tb[FRA_DST] ||
477479
frh->dst_len > (ops->addr_size * 8) ||
478-
nla_len(tb[FRA_DST]) != ops->addr_size)
480+
nla_len(tb[FRA_DST]) != ops->addr_size) {
481+
NL_SET_ERR_MSG(extack, "Invalid dst address");
479482
goto errout;
483+
}
480484

481485
nlrule = kzalloc(ops->rule_size, GFP_KERNEL);
482486
if (!nlrule) {
@@ -537,6 +541,7 @@ static int fib_nl2rule(struct sk_buff *skb, struct nlmsghdr *nlh,
537541
nlrule->l3mdev = nla_get_u8(tb[FRA_L3MDEV]);
538542
if (nlrule->l3mdev != 1)
539543
#endif
544+
NL_SET_ERR_MSG(extack, "Invalid l3mdev");
540545
goto errout_free;
541546
}
542547

@@ -554,31 +559,41 @@ static int fib_nl2rule(struct sk_buff *skb, struct nlmsghdr *nlh,
554559
nlrule->suppress_ifgroup = -1;
555560

556561
if (tb[FRA_GOTO]) {
557-
if (nlrule->action != FR_ACT_GOTO)
562+
if (nlrule->action != FR_ACT_GOTO) {
563+
NL_SET_ERR_MSG(extack, "Unexpected goto");
558564
goto errout_free;
565+
}
559566

560567
nlrule->target = nla_get_u32(tb[FRA_GOTO]);
561568
/* Backward jumps are prohibited to avoid endless loops */
562-
if (nlrule->target <= nlrule->pref)
569+
if (nlrule->target <= nlrule->pref) {
570+
NL_SET_ERR_MSG(extack, "Backward goto not supported");
563571
goto errout_free;
572+
}
564573
} else if (nlrule->action == FR_ACT_GOTO) {
574+
NL_SET_ERR_MSG(extack, "Missing goto target for action goto");
565575
goto errout_free;
566576
}
567577

568-
if (nlrule->l3mdev && nlrule->table)
578+
if (nlrule->l3mdev && nlrule->table) {
579+
NL_SET_ERR_MSG(extack, "l3mdev and table are mutually exclusive");
569580
goto errout_free;
581+
}
570582

571583
if (tb[FRA_UID_RANGE]) {
572584
if (current_user_ns() != net->user_ns) {
573585
err = -EPERM;
586+
NL_SET_ERR_MSG(extack, "No permission to set uid");
574587
goto errout_free;
575588
}
576589

577590
nlrule->uid_range = nla_get_kuid_range(tb);
578591

579592
if (!uid_range_set(&nlrule->uid_range) ||
580-
!uid_lte(nlrule->uid_range.start, nlrule->uid_range.end))
593+
!uid_lte(nlrule->uid_range.start, nlrule->uid_range.end)) {
594+
NL_SET_ERR_MSG(extack, "Invalid uid range");
581595
goto errout_free;
596+
}
582597
} else {
583598
nlrule->uid_range = fib_kuid_range_unset;
584599
}
@@ -589,15 +604,19 @@ static int fib_nl2rule(struct sk_buff *skb, struct nlmsghdr *nlh,
589604
if (tb[FRA_SPORT_RANGE]) {
590605
err = nla_get_port_range(tb[FRA_SPORT_RANGE],
591606
&nlrule->sport_range);
592-
if (err)
607+
if (err) {
608+
NL_SET_ERR_MSG(extack, "Invalid sport range");
593609
goto errout_free;
610+
}
594611
}
595612

596613
if (tb[FRA_DPORT_RANGE]) {
597614
err = nla_get_port_range(tb[FRA_DPORT_RANGE],
598615
&nlrule->dport_range);
599-
if (err)
616+
if (err) {
617+
NL_SET_ERR_MSG(extack, "Invalid dport range");
600618
goto errout_free;
619+
}
601620
}
602621

603622
*rule = nlrule;
@@ -621,18 +640,23 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
621640
int err = -EINVAL, unresolved = 0;
622641
bool user_priority = false;
623642

624-
if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh)))
643+
if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh))) {
644+
NL_SET_ERR_MSG(extack, "Invalid msg length");
625645
goto errout;
646+
}
626647

627648
ops = lookup_rules_ops(net, frh->family);
628649
if (!ops) {
629650
err = -EAFNOSUPPORT;
651+
NL_SET_ERR_MSG(extack, "Rule family not supported");
630652
goto errout;
631653
}
632654

633655
err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy, extack);
634-
if (err < 0)
656+
if (err < 0) {
657+
NL_SET_ERR_MSG(extack, "Error parsing msg");
635658
goto errout;
659+
}
636660

637661
err = fib_nl2rule(skb, nlh, extack, ops, tb, &rule, &user_priority);
638662
if (err)
@@ -644,7 +668,7 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
644668
goto errout_free;
645669
}
646670

647-
err = ops->configure(rule, skb, frh, tb);
671+
err = ops->configure(rule, skb, frh, tb, extack);
648672
if (err < 0)
649673
goto errout_free;
650674

@@ -723,18 +747,23 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh,
723747
int err = -EINVAL;
724748
bool user_priority = false;
725749

726-
if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh)))
750+
if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh))) {
751+
NL_SET_ERR_MSG(extack, "Invalid msg length");
727752
goto errout;
753+
}
728754

729755
ops = lookup_rules_ops(net, frh->family);
730756
if (ops == NULL) {
731757
err = -EAFNOSUPPORT;
758+
NL_SET_ERR_MSG(extack, "Rule family not supported");
732759
goto errout;
733760
}
734761

735762
err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy, extack);
736-
if (err < 0)
763+
if (err < 0) {
764+
NL_SET_ERR_MSG(extack, "Error parsing msg");
737765
goto errout;
766+
}
738767

739768
err = fib_nl2rule(skb, nlh, extack, ops, tb, &nlrule, &user_priority);
740769
if (err)

net/decnet/dn_rules.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,16 @@ static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
121121

122122
static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
123123
struct fib_rule_hdr *frh,
124-
struct nlattr **tb)
124+
struct nlattr **tb,
125+
struct netlink_ext_ack *extack)
125126
{
126127
int err = -EINVAL;
127128
struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
128129

129-
if (frh->tos)
130+
if (frh->tos) {
131+
NL_SET_ERR_MSG(extack, "Invalid tos value");
130132
goto errout;
133+
}
131134

132135
if (rule->table == RT_TABLE_UNSPEC) {
133136
if (rule->action == FR_ACT_TO_TBL) {

net/ipv4/fib_rules.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,14 +213,17 @@ static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = {
213213

214214
static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
215215
struct fib_rule_hdr *frh,
216-
struct nlattr **tb)
216+
struct nlattr **tb,
217+
struct netlink_ext_ack *extack)
217218
{
218219
struct net *net = sock_net(skb->sk);
219220
int err = -EINVAL;
220221
struct fib4_rule *rule4 = (struct fib4_rule *) rule;
221222

222-
if (frh->tos & ~IPTOS_TOS_MASK)
223+
if (frh->tos & ~IPTOS_TOS_MASK) {
224+
NL_SET_ERR_MSG(extack, "Invalid tos");
223225
goto errout;
226+
}
224227

225228
/* split local/main if they are not already split */
226229
err = fib_unmerge(net);

net/ipv4/ipmr.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ static const struct nla_policy ipmr_rule_policy[FRA_MAX + 1] = {
201201
};
202202

203203
static int ipmr_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
204-
struct fib_rule_hdr *frh, struct nlattr **tb)
204+
struct fib_rule_hdr *frh, struct nlattr **tb,
205+
struct netlink_ext_ack *extack)
205206
{
206207
return 0;
207208
}

net/ipv6/fib6_rules.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,18 @@ static const struct nla_policy fib6_rule_policy[FRA_MAX+1] = {
245245

246246
static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
247247
struct fib_rule_hdr *frh,
248-
struct nlattr **tb)
248+
struct nlattr **tb,
249+
struct netlink_ext_ack *extack)
249250
{
250251
int err = -EINVAL;
251252
struct net *net = sock_net(skb->sk);
252253
struct fib6_rule *rule6 = (struct fib6_rule *) rule;
253254

254255
if (rule->action == FR_ACT_TO_TBL && !rule->l3mdev) {
255-
if (rule->table == RT6_TABLE_UNSPEC)
256+
if (rule->table == RT6_TABLE_UNSPEC) {
257+
NL_SET_ERR_MSG(extack, "Invalid table");
256258
goto errout;
259+
}
257260

258261
if (fib6_new_table(net, rule->table) == NULL) {
259262
err = -ENOBUFS;

net/ipv6/ip6mr.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ static const struct nla_policy ip6mr_rule_policy[FRA_MAX + 1] = {
180180
};
181181

182182
static int ip6mr_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
183-
struct fib_rule_hdr *frh, struct nlattr **tb)
183+
struct fib_rule_hdr *frh, struct nlattr **tb,
184+
struct netlink_ext_ack *extack)
184185
{
185186
return 0;
186187
}

0 commit comments

Comments
 (0)