net/ipv4: Initialize proto and ports in flow struct
authorDavid Ahern <dsahern@gmail.com>
Wed, 16 May 2018 20:36:40 +0000 (13:36 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 17 May 2018 18:55:21 +0000 (14:55 -0400)
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>
net/ipv4/fib_frontend.c
net/ipv4/netfilter/ipt_rpfilter.c
net/ipv4/route.c

index f05afaf3235c0500a9087eae6365b7001aa64663..4d622112bf95fabd9d0e87c64f1e27138a3c1556 100644 (file)
@@ -326,10 +326,11 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
                                 u8 tos, int oif, struct net_device *dev,
                                 int rpf, struct in_device *idev, u32 *itag)
 {
+       struct net *net = dev_net(dev);
+       struct flow_keys flkeys;
        int ret, no_addr;
        struct fib_result res;
        struct flowi4 fl4;
-       struct net *net = dev_net(dev);
        bool dev_match;
 
        fl4.flowi4_oif = 0;
@@ -347,6 +348,11 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
        no_addr = idev->ifa_list == NULL;
 
        fl4.flowi4_mark = IN_DEV_SRC_VMARK(idev) ? skb->mark : 0;
+       if (!fib4_rules_early_flow_dissect(net, skb, &fl4, &flkeys)) {
+               fl4.flowi4_proto = 0;
+               fl4.fl4_sport = 0;
+               fl4.fl4_dport = 0;
+       }
 
        trace_fib_validate_source(dev, &fl4);
 
index fd01f13c896a153c6ec54b2df5503da6c311cf4f..12843c9ef1421d204fba6bea42a85615e2e69cc7 100644 (file)
@@ -89,10 +89,10 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
                        return true ^ invert;
        }
 
+       memset(&flow, 0, sizeof(flow));
        flow.flowi4_iif = LOOPBACK_IFINDEX;
        flow.daddr = iph->saddr;
        flow.saddr = rpfilter_get_saddr(iph->daddr);
-       flow.flowi4_oif = 0;
        flow.flowi4_mark = info->flags & XT_RPFILTER_VALID_MARK ? skb->mark : 0;
        flow.flowi4_tos = RT_TOS(iph->tos);
        flow.flowi4_scope = RT_SCOPE_UNIVERSE;
index 29268efad24777b6839923e25d7bf138c9cf0643..2cfa1b518f8d6368a563c1ae14d7dff7ce43e473 100644 (file)
@@ -1961,8 +1961,13 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        fl4.saddr = saddr;
        fl4.flowi4_uid = sock_net_uid(net, NULL);
 
-       if (fib4_rules_early_flow_dissect(net, skb, &fl4, &_flkeys))
+       if (fib4_rules_early_flow_dissect(net, skb, &fl4, &_flkeys)) {
                flkeys = &_flkeys;
+       } else {
+               fl4.flowi4_proto = 0;
+               fl4.fl4_sport = 0;
+               fl4.fl4_dport = 0;
+       }
 
        err = fib_lookup(net, &fl4, res, 0);
        if (err != 0) {