|
@@ -1505,6 +1505,7 @@ static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = {
|
|
|
static const struct nla_policy ifla_xdp_policy[IFLA_XDP_MAX + 1] = {
|
|
|
[IFLA_XDP_FD] = { .type = NLA_S32 },
|
|
|
[IFLA_XDP_ATTACHED] = { .type = NLA_U8 },
|
|
|
+ [IFLA_XDP_FLAGS] = { .type = NLA_U32 },
|
|
|
};
|
|
|
|
|
|
static const struct rtnl_link_ops *linkinfo_to_kind_ops(const struct nlattr *nla)
|
|
@@ -2164,6 +2165,7 @@ static int do_setlink(const struct sk_buff *skb,
|
|
|
|
|
|
if (tb[IFLA_XDP]) {
|
|
|
struct nlattr *xdp[IFLA_XDP_MAX + 1];
|
|
|
+ u32 xdp_flags = 0;
|
|
|
|
|
|
err = nla_parse_nested(xdp, IFLA_XDP_MAX, tb[IFLA_XDP],
|
|
|
ifla_xdp_policy);
|
|
@@ -2174,9 +2176,19 @@ static int do_setlink(const struct sk_buff *skb,
|
|
|
err = -EINVAL;
|
|
|
goto errout;
|
|
|
}
|
|
|
+
|
|
|
+ if (xdp[IFLA_XDP_FLAGS]) {
|
|
|
+ xdp_flags = nla_get_u32(xdp[IFLA_XDP_FLAGS]);
|
|
|
+ if (xdp_flags & ~XDP_FLAGS_MASK) {
|
|
|
+ err = -EINVAL;
|
|
|
+ goto errout;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (xdp[IFLA_XDP_FD]) {
|
|
|
err = dev_change_xdp_fd(dev,
|
|
|
- nla_get_s32(xdp[IFLA_XDP_FD]));
|
|
|
+ nla_get_s32(xdp[IFLA_XDP_FD]),
|
|
|
+ xdp_flags);
|
|
|
if (err)
|
|
|
goto errout;
|
|
|
status |= DO_SETLINK_NOTIFY;
|