diff options
| -rw-r--r-- | net/core/rtnetlink.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 233b5ae87583..1063996f8317 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -1244,6 +1244,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1244 | struct nlattr *tb[IFLA_MAX+1]; | 1244 | struct nlattr *tb[IFLA_MAX+1]; |
| 1245 | u32 ext_filter_mask = 0; | 1245 | u32 ext_filter_mask = 0; |
| 1246 | int err; | 1246 | int err; |
| 1247 | int hdrlen; | ||
| 1247 | 1248 | ||
| 1248 | s_h = cb->args[0]; | 1249 | s_h = cb->args[0]; |
| 1249 | s_idx = cb->args[1]; | 1250 | s_idx = cb->args[1]; |
| @@ -1251,8 +1252,17 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1251 | rcu_read_lock(); | 1252 | rcu_read_lock(); |
| 1252 | cb->seq = net->dev_base_seq; | 1253 | cb->seq = net->dev_base_seq; |
| 1253 | 1254 | ||
| 1254 | if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, | 1255 | /* A hack to preserve kernel<->userspace interface. |
| 1255 | ifla_policy) >= 0) { | 1256 | * The correct header is ifinfomsg. It is consistent with rtnl_getlink. |
| 1257 | * However, before Linux v3.9 the code here assumed rtgenmsg and that's | ||
| 1258 | * what iproute2 < v3.9.0 used. | ||
| 1259 | * We can detect the old iproute2. Even including the IFLA_EXT_MASK | ||
| 1260 | * attribute, its netlink message is shorter than struct ifinfomsg. | ||
| 1261 | */ | ||
| 1262 | hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ? | ||
| 1263 | sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg); | ||
| 1264 | |||
| 1265 | if (nlmsg_parse(cb->nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) { | ||
| 1256 | 1266 | ||
| 1257 | if (tb[IFLA_EXT_MASK]) | 1267 | if (tb[IFLA_EXT_MASK]) |
| 1258 | ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); | 1268 | ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); |
| @@ -2126,9 +2136,13 @@ static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 2126 | struct nlattr *tb[IFLA_MAX+1]; | 2136 | struct nlattr *tb[IFLA_MAX+1]; |
| 2127 | u32 ext_filter_mask = 0; | 2137 | u32 ext_filter_mask = 0; |
| 2128 | u16 min_ifinfo_dump_size = 0; | 2138 | u16 min_ifinfo_dump_size = 0; |
| 2139 | int hdrlen; | ||
| 2140 | |||
| 2141 | /* Same kernel<->userspace interface hack as in rtnl_dump_ifinfo. */ | ||
| 2142 | hdrlen = nlmsg_len(nlh) < sizeof(struct ifinfomsg) ? | ||
| 2143 | sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg); | ||
| 2129 | 2144 | ||
| 2130 | if (nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, | 2145 | if (nlmsg_parse(nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) { |
| 2131 | ifla_policy) >= 0) { | ||
| 2132 | if (tb[IFLA_EXT_MASK]) | 2146 | if (tb[IFLA_EXT_MASK]) |
| 2133 | ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); | 2147 | ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); |
| 2134 | } | 2148 | } |
