Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
authorDavid S. Miller <davem@davemloft.net>
Sat, 3 Jul 2010 05:42:06 +0000 (22:42 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sat, 3 Jul 2010 05:42:06 +0000 (22:42 -0700)
1  2 
net/bridge/br_netfilter.c
net/bridge/br_private.h
net/netfilter/ipvs/ip_vs_conn.c

@@@ -55,6 -55,9 +55,9 @@@ static int brnf_call_arptables __read_m
  static int brnf_filter_vlan_tagged __read_mostly = 0;
  static int brnf_filter_pppoe_tagged __read_mostly = 0;
  #else
+ #define brnf_call_iptables 1
+ #define brnf_call_ip6tables 1
+ #define brnf_call_arptables 1
  #define brnf_filter_vlan_tagged 0
  #define brnf_filter_pppoe_tagged 0
  #endif
@@@ -127,17 -130,16 +130,17 @@@ void br_netfilter_rtable_init(struct ne
  
  static inline struct rtable *bridge_parent_rtable(const struct net_device *dev)
  {
 -      struct net_bridge_port *port = rcu_dereference(dev->br_port);
 -
 -      return port ? &port->br->fake_rtable : NULL;
 +      if (!br_port_exists(dev))
 +              return NULL;
 +      return &br_port_get_rcu(dev)->br->fake_rtable;
  }
  
  static inline struct net_device *bridge_parent(const struct net_device *dev)
  {
 -      struct net_bridge_port *port = rcu_dereference(dev->br_port);
 +      if (!br_port_exists(dev))
 +              return NULL;
  
 -      return port ? port->br->dev : NULL;
 +      return br_port_get_rcu(dev)->br->dev;
  }
  
  static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
@@@ -544,25 -546,30 +547,30 @@@ static unsigned int br_nf_pre_routing(u
                                      const struct net_device *out,
                                      int (*okfn)(struct sk_buff *))
  {
+       struct net_bridge_port *p;
+       struct net_bridge *br;
        struct iphdr *iph;
        __u32 len = nf_bridge_encap_header_len(skb);
  
        if (unlikely(!pskb_may_pull(skb, len)))
                goto out;
  
 -      p = rcu_dereference(in->br_port);
++      p = br_port_get_rcu(in);
+       if (p == NULL)
+               goto out;
+       br = p->br;
        if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) ||
            IS_PPPOE_IPV6(skb)) {
- #ifdef CONFIG_SYSCTL
-               if (!brnf_call_ip6tables)
+               if (!brnf_call_ip6tables && !br->nf_call_ip6tables)
                        return NF_ACCEPT;
- #endif
                nf_bridge_pull_encap_header_rcsum(skb);
                return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
        }
- #ifdef CONFIG_SYSCTL
-       if (!brnf_call_iptables)
+       if (!brnf_call_iptables && !br->nf_call_iptables)
                return NF_ACCEPT;
- #endif
  
        if (skb->protocol != htons(ETH_P_IP) && !IS_VLAN_IP(skb) &&
            !IS_PPPOE_IP(skb))
@@@ -715,12 -722,17 +723,17 @@@ static unsigned int br_nf_forward_arp(u
                                      const struct net_device *out,
                                      int (*okfn)(struct sk_buff *))
  {
+       struct net_bridge_port *p;
+       struct net_bridge *br;
        struct net_device **d = (struct net_device **)(skb->cb);
  
- #ifdef CONFIG_SYSCTL
-       if (!brnf_call_arptables)
 -      p = rcu_dereference(out->br_port);
++      p = br_port_get_rcu(out);
+       if (p == NULL)
+               return NF_ACCEPT;
+       br = p->br;
+       if (!brnf_call_arptables && !br->nf_call_arptables)
                return NF_ACCEPT;
- #endif
  
        if (skb->protocol != htons(ETH_P_ARP)) {
                if (!IS_VLAN_ARP(skb))
diff --combined net/bridge/br_private.h
@@@ -15,8 -15,6 +15,8 @@@
  
  #include <linux/netdevice.h>
  #include <linux/if_bridge.h>
 +#include <linux/netpoll.h>
 +#include <linux/u64_stats_sync.h>
  #include <net/route.h>
  
  #define BR_HASH_BITS 8
@@@ -145,23 -143,13 +145,23 @@@ struct net_bridge_por
  #ifdef CONFIG_SYSFS
        char                            sysfs_name[IFNAMSIZ];
  #endif
 +
 +#ifdef CONFIG_NET_POLL_CONTROLLER
 +      struct netpoll                  *np;
 +#endif
  };
  
 +#define br_port_get_rcu(dev) \
 +      ((struct net_bridge_port *) rcu_dereference(dev->rx_handler_data))
 +#define br_port_get(dev) ((struct net_bridge_port *) dev->rx_handler_data)
 +#define br_port_exists(dev) (dev->priv_flags & IFF_BRIDGE_PORT)
 +
  struct br_cpu_netstats {
 -      unsigned long   rx_packets;
 -      unsigned long   rx_bytes;
 -      unsigned long   tx_packets;
 -      unsigned long   tx_bytes;
 +      u64                     rx_packets;
 +      u64                     rx_bytes;
 +      u64                     tx_packets;
 +      u64                     tx_bytes;
 +      struct u64_stats_sync   syncp;
  };
  
  struct net_bridge
        unsigned long                   feature_mask;
  #ifdef CONFIG_BRIDGE_NETFILTER
        struct rtable                   fake_rtable;
+       bool                            nf_call_iptables;
+       bool                            nf_call_ip6tables;
+       bool                            nf_call_arptables;
  #endif
        unsigned long                   flags;
  #define BR_SET_MAC_ADDR               0x00000001
@@@ -285,41 -276,16 +288,41 @@@ extern void br_dev_setup(struct net_dev
  extern netdev_tx_t br_dev_xmit(struct sk_buff *skb,
                               struct net_device *dev);
  #ifdef CONFIG_NET_POLL_CONTROLLER
 -extern void br_netpoll_cleanup(struct net_device *dev);
 -extern void br_netpoll_enable(struct net_bridge *br,
 -                            struct net_device *dev);
 -extern void br_netpoll_disable(struct net_bridge *br,
 -                             struct net_device *dev);
 +static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br)
 +{
 +      return br->dev->npinfo;
 +}
 +
 +static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
 +                                     struct sk_buff *skb)
 +{
 +      struct netpoll *np = p->np;
 +
 +      if (np)
 +              netpoll_send_skb(np, skb);
 +}
 +
 +extern int br_netpoll_enable(struct net_bridge_port *p);
 +extern void br_netpoll_disable(struct net_bridge_port *p);
  #else
 -#define br_netpoll_cleanup(br)
 -#define br_netpoll_enable(br, dev)
 -#define br_netpoll_disable(br, dev)
 +static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br)
 +{
 +      return NULL;
 +}
 +
 +static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
 +                                     struct sk_buff *skb)
 +{
 +}
  
 +static inline int br_netpoll_enable(struct net_bridge_port *p)
 +{
 +      return 0;
 +}
 +
 +static inline void br_netpoll_disable(struct net_bridge_port *p)
 +{
 +}
  #endif
  
  /* br_fdb.c */
@@@ -158,11 -158,13 +158,14 @@@ static inline int ip_vs_conn_hash(struc
        unsigned hash;
        int ret;
  
+       if (cp->flags & IP_VS_CONN_F_ONE_PACKET)
+               return 0;
        /* Hash by protocol, client address and port */
        hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport);
  
        ct_write_lock(hash);
 +      spin_lock(&cp->lock);
  
        if (!(cp->flags & IP_VS_CONN_F_HASHED)) {
                list_add(&cp->c_list, &ip_vs_conn_tab[hash]);
                ret = 0;
        }
  
 +      spin_unlock(&cp->lock);
        ct_write_unlock(hash);
  
        return ret;
@@@ -195,7 -196,6 +198,7 @@@ static inline int ip_vs_conn_unhash(str
        hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport);
  
        ct_write_lock(hash);
 +      spin_lock(&cp->lock);
  
        if (cp->flags & IP_VS_CONN_F_HASHED) {
                list_del(&cp->c_list);
        } else
                ret = 0;
  
 +      spin_unlock(&cp->lock);
        ct_write_unlock(hash);
  
        return ret;
@@@ -359,8 -358,9 +362,9 @@@ struct ip_vs_conn *ip_vs_conn_out_ge
   */
  void ip_vs_conn_put(struct ip_vs_conn *cp)
  {
-       /* reset it expire in its timeout */
-       mod_timer(&cp->timer, jiffies+cp->timeout);
+       unsigned long t = (cp->flags & IP_VS_CONN_F_ONE_PACKET) ?
+               0 : cp->timeout;
+       mod_timer(&cp->timer, jiffies+t);
  
        __ip_vs_conn_put(cp);
  }
@@@ -653,7 -653,7 +657,7 @@@ static void ip_vs_conn_expire(unsigned 
        /*
         *      unhash it if it is hashed in the conn table
         */
-       if (!ip_vs_conn_unhash(cp))
+       if (!ip_vs_conn_unhash(cp) && !(cp->flags & IP_VS_CONN_F_ONE_PACKET))
                goto expire_later;
  
        /*