Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/ipv4: Initialize proto and ports in flow struct

Updating the FIB tracepoint for the recent change to allow rules using
the protocol and ports exposed a few places where the entries in the flow
struct are not initialized.

For __fib_validate_source add the call to fib4_rules_early_flow_dissect
since it is invoked for the input path. For netfilter, add the memset on
the flow struct to avoid future problems like this. In ip_route_input_slow
need to set the fields if the skb dissection does not happen.

Fixes: bfff4862653b ("net: fib_rules: support for match on ip_proto, sport and dport")
Signed-off-by: David Ahern <dsahern@gmail.com>
Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

David Ahern and committed by
David S. Miller
5a847a6e 8ab6ffba

+14 -3
+7 -1
net/ipv4/fib_frontend.c
··· 326 326 u8 tos, int oif, struct net_device *dev, 327 327 int rpf, struct in_device *idev, u32 *itag) 328 328 { 329 + struct net *net = dev_net(dev); 330 + struct flow_keys flkeys; 329 331 int ret, no_addr; 330 332 struct fib_result res; 331 333 struct flowi4 fl4; 332 - struct net *net = dev_net(dev); 333 334 bool dev_match; 334 335 335 336 fl4.flowi4_oif = 0; ··· 348 347 no_addr = idev->ifa_list == NULL; 349 348 350 349 fl4.flowi4_mark = IN_DEV_SRC_VMARK(idev) ? skb->mark : 0; 350 + if (!fib4_rules_early_flow_dissect(net, skb, &fl4, &flkeys)) { 351 + fl4.flowi4_proto = 0; 352 + fl4.fl4_sport = 0; 353 + fl4.fl4_dport = 0; 354 + } 351 355 352 356 trace_fib_validate_source(dev, &fl4); 353 357
+1 -1
net/ipv4/netfilter/ipt_rpfilter.c
··· 89 89 return true ^ invert; 90 90 } 91 91 92 + memset(&flow, 0, sizeof(flow)); 92 93 flow.flowi4_iif = LOOPBACK_IFINDEX; 93 94 flow.daddr = iph->saddr; 94 95 flow.saddr = rpfilter_get_saddr(iph->daddr); 95 - flow.flowi4_oif = 0; 96 96 flow.flowi4_mark = info->flags & XT_RPFILTER_VALID_MARK ? skb->mark : 0; 97 97 flow.flowi4_tos = RT_TOS(iph->tos); 98 98 flow.flowi4_scope = RT_SCOPE_UNIVERSE;
+6 -1
net/ipv4/route.c
··· 1961 1961 fl4.saddr = saddr; 1962 1962 fl4.flowi4_uid = sock_net_uid(net, NULL); 1963 1963 1964 - if (fib4_rules_early_flow_dissect(net, skb, &fl4, &_flkeys)) 1964 + if (fib4_rules_early_flow_dissect(net, skb, &fl4, &_flkeys)) { 1965 1965 flkeys = &_flkeys; 1966 + } else { 1967 + fl4.flowi4_proto = 0; 1968 + fl4.fl4_sport = 0; 1969 + fl4.fl4_dport = 0; 1970 + } 1966 1971 1967 1972 err = fib_lookup(net, &fl4, res, 0); 1968 1973 if (err != 0) {