]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge branch 'master' of git://1984.lsi.us.es/nf-next
authorDavid S. Miller <davem@davemloft.net>
Thu, 13 Sep 2012 18:24:31 +0000 (14:24 -0400)
committerDavid S. Miller <davem@davemloft.net>
Thu, 13 Sep 2012 18:24:31 +0000 (14:24 -0400)
Pablo Neira Ayuso says:

====================
The following patchset contains four Netfilter updates, mostly targeting
to fix issues added with IPv6 NAT, and one little IPVS update for net-next:

* Remove unneeded conditional free of skb in nfnetlink_queue, from
  Wei Yongjun.

* One semantic path from coccinelle detected the use of list_del +
  INIT_LIST_HEAD, instead of list_del_init, again from Wei Yongjun.

* Fix out-of-bound memory access in the NAT address selection, from
  Florian Westphal. This was introduced with the IPv6 NAT patches.

* Two fixes for crashes that were introduced in the recently merged
  IPv6 NAT support, from myself.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
138 files changed:
arch/x86/net/bpf_jit_comp.c
crypto/crypto_user.c
drivers/connector/connector.c
drivers/infiniband/core/netlink.c
drivers/infiniband/hw/cxgb4/qp.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
drivers/net/ethernet/broadcom/cnic.c
drivers/net/ethernet/broadcom/cnic.h
drivers/net/ethernet/broadcom/cnic_if.h
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/sge.c
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/intel/igb/igb.h
drivers/net/ethernet/intel/igb/igb_ethtool.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ieee802154/Kconfig
drivers/net/ieee802154/Makefile
drivers/net/ieee802154/mrf24j40.c [new file with mode: 0644]
drivers/net/phy/mdio-mux-mmioreg.c
drivers/net/team/team.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/sierra_net.c
drivers/net/wireless/mac80211_hwsim.c
drivers/scsi/scsi_netlink.c
drivers/scsi/scsi_transport_iscsi.c
drivers/staging/gdm72xx/netlink_k.c
fs/dlm/netlink.c
include/linux/Kbuild
include/linux/etherdevice.h
include/linux/filter.h
include/linux/netdevice.h
include/linux/netlink.h
include/linux/tcp_metrics.h [new file with mode: 0644]
include/net/cfg80211.h
include/net/genetlink.h
include/net/ip6_fib.h
include/net/netfilter/nf_conntrack_ecache.h
include/net/netlink.h
include/net/nfc/nfc.h
include/net/route.h
include/net/scm.h
include/net/xfrm.h
kernel/audit.c
kernel/taskstats.c
lib/kobject_uevent.c
net/Kconfig
net/bridge/br_fdb.c
net/bridge/br_netlink.c
net/bridge/netfilter/ebt_ulog.c
net/can/gw.c
net/core/fib_rules.c
net/core/filter.c
net/core/neighbour.c
net/core/net-sysfs.c
net/core/rtnetlink.c
net/core/scm.c
net/core/sock_diag.c
net/dcb/dcbnl.c
net/decnet/dn_dev.c
net/decnet/dn_route.c
net/decnet/dn_table.c
net/decnet/netfilter/dn_rtmsg.c
net/ieee802154/nl-mac.c
net/ieee802154/nl-phy.c
net/ipv4/af_inet.c
net/ipv4/arp.c
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/fib_rules.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/igmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_diag.c
net/ipv4/ipmr.c
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/route.c
net/ipv4/tcp_metrics.c
net/ipv4/udp_diag.c
net/ipv6/addrconf.c
net/ipv6/addrlabel.c
net/ipv6/ip6_output.c
net/ipv6/ip6mr.c
net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
net/ipv6/route.c
net/irda/irnetlink.c
net/key/af_key.c
net/l2tp/l2tp_eth.c
net/l2tp/l2tp_netlink.c
net/netfilter/ipset/ip_set_core.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/nf_conntrack_ecache.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nfnetlink.c
net/netfilter/nfnetlink_acct.c
net/netfilter/nfnetlink_cthelper.c
net/netfilter/nfnetlink_cttimeout.c
net/netfilter/nfnetlink_log.c
net/netfilter/nfnetlink_queue_core.c
net/netlabel/netlabel_cipso_v4.c
net/netlabel/netlabel_mgmt.c
net/netlabel/netlabel_unlabeled.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/nfc/netlink.c
net/openvswitch/actions.c
net/openvswitch/datapath.c
net/openvswitch/datapath.h
net/openvswitch/dp_notify.c
net/openvswitch/flow.c
net/openvswitch/flow.h
net/openvswitch/vport-internal_dev.c
net/openvswitch/vport-netdev.c
net/openvswitch/vport.c
net/openvswitch/vport.h
net/packet/diag.c
net/phonet/pn_netlink.c
net/sched/act_api.c
net/sched/cls_api.c
net/sched/sch_api.c
net/sched/sch_generic.c
net/sctp/outqueue.c
net/socket.c
net/tipc/netlink.c
net/unix/diag.c
net/wireless/core.h
net/wireless/mlme.c
net/wireless/nl80211.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
security/selinux/netlink.c

index 33643a8bcbbb0f1887dc2f815fe469aaf0e0507a..106c57829120b95c61822a51163bcc5339db96ef 100644 (file)
@@ -280,6 +280,31 @@ void bpf_jit_compile(struct sk_filter *fp)
                                }
                                EMIT4(0x31, 0xd2, 0xf7, 0xf3); /* xor %edx,%edx; div %ebx */
                                break;
+                       case BPF_S_ALU_MOD_X: /* A %= X; */
+                               seen |= SEEN_XREG;
+                               EMIT2(0x85, 0xdb);      /* test %ebx,%ebx */
+                               if (pc_ret0 > 0) {
+                                       /* addrs[pc_ret0 - 1] is start address of target
+                                        * (addrs[i] - 6) is the address following this jmp
+                                        * ("xor %edx,%edx; div %ebx;mov %edx,%eax" being 6 bytes long)
+                                        */
+                                       EMIT_COND_JMP(X86_JE, addrs[pc_ret0 - 1] -
+                                                               (addrs[i] - 6));
+                               } else {
+                                       EMIT_COND_JMP(X86_JNE, 2 + 5);
+                                       CLEAR_A();
+                                       EMIT1_off32(0xe9, cleanup_addr - (addrs[i] - 6)); /* jmp .+off32 */
+                               }
+                               EMIT2(0x31, 0xd2);      /* xor %edx,%edx */
+                               EMIT2(0xf7, 0xf3);      /* div %ebx */
+                               EMIT2(0x89, 0xd0);      /* mov %edx,%eax */
+                               break;
+                       case BPF_S_ALU_MOD_K: /* A %= K; */
+                               EMIT2(0x31, 0xd2);      /* xor %edx,%edx */
+                               EMIT1(0xb9);EMIT(K, 4); /* mov imm32,%ecx */
+                               EMIT2(0xf7, 0xf1);      /* div %ecx */
+                               EMIT2(0x89, 0xd0);      /* mov %edx,%eax */
+                               break;
                        case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */
                                EMIT3(0x48, 0x69, 0xc0); /* imul imm32,%rax,%rax */
                                EMIT(K, 4);
index ba2c611154af5e0df373a04b22eed782da0daac5..6bba414d0c619d1fba31c1136aea411a09a930c0 100644 (file)
@@ -166,7 +166,7 @@ static int crypto_report_alg(struct crypto_alg *alg,
        struct crypto_user_alg *ualg;
        int err = 0;
 
-       nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, info->nlmsg_seq,
+       nlh = nlmsg_put(skb, NETLINK_CB(in_skb).portid, info->nlmsg_seq,
                        CRYPTO_MSG_GETALG, sizeof(*ualg), info->nlmsg_flags);
        if (!nlh) {
                err = -EMSGSIZE;
@@ -216,7 +216,7 @@ static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
        if (err)
                return err;
 
-       return nlmsg_unicast(crypto_nlsk, skb, NETLINK_CB(in_skb).pid);
+       return nlmsg_unicast(crypto_nlsk, skb, NETLINK_CB(in_skb).portid);
 }
 
 static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb)
@@ -500,8 +500,7 @@ static int __init crypto_user_init(void)
                .input  = crypto_netlink_rcv,
        };
 
-       crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO,
-                                           THIS_MODULE, &cfg);
+       crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO, &cfg);
        if (!crypto_nlsk)
                return -ENOMEM;
 
index 82fa4f0f91d6ebdb13534997807b5da125e126fa..965b7811e04f37100151dc441b7713cdee065bbf 100644 (file)
@@ -264,8 +264,7 @@ static int __devinit cn_init(void)
                .input  = dev->input,
        };
 
-       dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR,
-                                        THIS_MODULE, &cfg);
+       dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR, &cfg);
        if (!dev->nls)
                return -EIO;
 
index 3ae2bfd310158d58dd6051961358010947070fdd..fe10a949aef9b6bd0533da3c4886933ee4a2091f 100644 (file)
@@ -177,7 +177,7 @@ int __init ibnl_init(void)
                .input  = ibnl_rcv,
        };
 
-       nls = netlink_kernel_create(&init_net, NETLINK_RDMA, THIS_MODULE, &cfg);
+       nls = netlink_kernel_create(&init_net, NETLINK_RDMA, &cfg);
        if (!nls) {
                pr_warn("Failed to create netlink socket\n");
                return -ENOMEM;
index 45aedf1d9338a2d9e274778fa025d496bb6f09fc..5213bab2d19bc2092c6f5cd948f5da8d5104736a 100644 (file)
@@ -1155,7 +1155,7 @@ static int ring_kernel_db(struct c4iw_qp *qhp, u32 qid, u16 inc)
                 */
                if (cxgb4_dbfifo_count(qhp->rhp->rdev.lldi.ports[0], 1) <
                    (qhp->rhp->rdev.lldi.dbfifo_int_thresh << 5)) {
-                       writel(V_QID(qid) | V_PIDX(inc), qhp->wq.db);
+                       writel(QID(qid) | PIDX(inc), qhp->wq.db);
                        break;
                }
                set_current_state(TASK_UNINTERRUPTIBLE);
index c37a68d68090e1326b6f491c9f4e28f26a78f87b..5bafcd9df9e0aaf6c640d9d7d18c92869314a22f 100644 (file)
@@ -1647,7 +1647,7 @@ static int bnx2x_get_eee(struct net_device *dev, struct ethtool_eee *edata)
                return -EOPNOTSUPP;
        }
 
-       eee_cfg = SHMEM2_RD(bp, eee_status[BP_PORT(bp)]);
+       eee_cfg = bp->link_vars.eee_status;
 
        edata->supported =
                bnx2x_eee_to_adv((eee_cfg & SHMEM_EEE_SUPPORTED_MASK) >>
@@ -1684,7 +1684,7 @@ static int bnx2x_set_eee(struct net_device *dev, struct ethtool_eee *edata)
                return -EOPNOTSUPP;
        }
 
-       eee_cfg = SHMEM2_RD(bp, eee_status[BP_PORT(bp)]);
+       eee_cfg = bp->link_vars.eee_status;
 
        if (!(eee_cfg & SHMEM_EEE_SUPPORTED_MASK)) {
                DP(BNX2X_MSG_ETHTOOL, "Board does not support EEE!\n");
index f4beb46c4709af8291ed7aecc373d7a72a366f59..c660afdbdf5636aae303ef189d4537e8ceafdc62 100644 (file)
@@ -1306,93 +1306,6 @@ int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
        return 0;
 }
 
-/******************************************************************/
-/*                     EEE section                                */
-/******************************************************************/
-static u8 bnx2x_eee_has_cap(struct link_params *params)
-{
-       struct bnx2x *bp = params->bp;
-
-       if (REG_RD(bp, params->shmem2_base) <=
-                  offsetof(struct shmem2_region, eee_status[params->port]))
-               return 0;
-
-       return 1;
-}
-
-static int bnx2x_eee_nvram_to_time(u32 nvram_mode, u32 *idle_timer)
-{
-       switch (nvram_mode) {
-       case PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED:
-               *idle_timer = EEE_MODE_NVRAM_BALANCED_TIME;
-               break;
-       case PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE:
-               *idle_timer = EEE_MODE_NVRAM_AGGRESSIVE_TIME;
-               break;
-       case PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY:
-               *idle_timer = EEE_MODE_NVRAM_LATENCY_TIME;
-               break;
-       default:
-               *idle_timer = 0;
-               break;
-       }
-
-       return 0;
-}
-
-static int bnx2x_eee_time_to_nvram(u32 idle_timer, u32 *nvram_mode)
-{
-       switch (idle_timer) {
-       case EEE_MODE_NVRAM_BALANCED_TIME:
-               *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED;
-               break;
-       case EEE_MODE_NVRAM_AGGRESSIVE_TIME:
-               *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE;
-               break;
-       case EEE_MODE_NVRAM_LATENCY_TIME:
-               *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY;
-               break;
-       default:
-               *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED;
-               break;
-       }
-
-       return 0;
-}
-
-static u32 bnx2x_eee_calc_timer(struct link_params *params)
-{
-       u32 eee_mode, eee_idle;
-       struct bnx2x *bp = params->bp;
-
-       if (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) {
-               if (params->eee_mode & EEE_MODE_OUTPUT_TIME) {
-                       /* time value in eee_mode --> used directly*/
-                       eee_idle = params->eee_mode & EEE_MODE_TIMER_MASK;
-               } else {
-                       /* hsi value in eee_mode --> time */
-                       if (bnx2x_eee_nvram_to_time(params->eee_mode &
-                                                   EEE_MODE_NVRAM_MASK,
-                                                   &eee_idle))
-                               return 0;
-               }
-       } else {
-               /* hsi values in nvram --> time*/
-               eee_mode = ((REG_RD(bp, params->shmem_base +
-                                   offsetof(struct shmem_region, dev_info.
-                                   port_feature_config[params->port].
-                                   eee_power_mode)) &
-                            PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >>
-                           PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT);
-
-               if (bnx2x_eee_nvram_to_time(eee_mode, &eee_idle))
-                       return 0;
-       }
-
-       return eee_idle;
-}
-
-
 /******************************************************************/
 /*                     PFC section                               */
 /******************************************************************/
@@ -1671,6 +1584,16 @@ static void bnx2x_umac_enable(struct link_params *params,
        REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
        udelay(50);
 
+       /* Configure UMAC for EEE */
+       if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
+               DP(NETIF_MSG_LINK, "configured UMAC for EEE\n");
+               REG_WR(bp, umac_base + UMAC_REG_UMAC_EEE_CTRL,
+                      UMAC_UMAC_EEE_CTRL_REG_EEE_EN);
+               REG_WR(bp, umac_base + UMAC_REG_EEE_WAKE_TIMER, 0x11);
+       } else {
+               REG_WR(bp, umac_base + UMAC_REG_UMAC_EEE_CTRL, 0x0);
+       }
+
        /* Set MAC address for source TX Pause/PFC frames (under SW reset) */
        REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR0,
               ((params->mac_addr[2] << 24) |
@@ -2529,16 +2452,6 @@ static void bnx2x_update_mng(struct link_params *params, u32 link_status)
                        port_mb[params->port].link_status), link_status);
 }
 
-static void bnx2x_update_mng_eee(struct link_params *params, u32 eee_status)
-{
-       struct bnx2x *bp = params->bp;
-
-       if (bnx2x_eee_has_cap(params))
-               REG_WR(bp, params->shmem2_base +
-                      offsetof(struct shmem2_region,
-                               eee_status[params->port]), eee_status);
-}
-
 static void bnx2x_update_pfc_nig(struct link_params *params,
                struct link_vars *vars,
                struct bnx2x_nig_brb_pfc_port_params *nig_params)
@@ -3231,6 +3144,245 @@ static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
                               EMAC_MDIO_STATUS_10MB);
        return rc;
 }
+
+/******************************************************************/
+/*                     EEE section                                */
+/******************************************************************/
+static u8 bnx2x_eee_has_cap(struct link_params *params)
+{
+       struct bnx2x *bp = params->bp;
+
+       if (REG_RD(bp, params->shmem2_base) <=
+                  offsetof(struct shmem2_region, eee_status[params->port]))
+               return 0;
+
+       return 1;
+}
+
+static int bnx2x_eee_nvram_to_time(u32 nvram_mode, u32 *idle_timer)
+{
+       switch (nvram_mode) {
+       case PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED:
+               *idle_timer = EEE_MODE_NVRAM_BALANCED_TIME;
+               break;
+       case PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE:
+               *idle_timer = EEE_MODE_NVRAM_AGGRESSIVE_TIME;
+               break;
+       case PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY:
+               *idle_timer = EEE_MODE_NVRAM_LATENCY_TIME;
+               break;
+       default:
+               *idle_timer = 0;
+               break;
+       }
+
+       return 0;
+}
+
+static int bnx2x_eee_time_to_nvram(u32 idle_timer, u32 *nvram_mode)
+{
+       switch (idle_timer) {
+       case EEE_MODE_NVRAM_BALANCED_TIME:
+               *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED;
+               break;
+       case EEE_MODE_NVRAM_AGGRESSIVE_TIME:
+               *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE;
+               break;
+       case EEE_MODE_NVRAM_LATENCY_TIME:
+               *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY;
+               break;
+       default:
+               *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED;
+               break;
+       }
+
+       return 0;
+}
+
+static u32 bnx2x_eee_calc_timer(struct link_params *params)
+{
+       u32 eee_mode, eee_idle;
+       struct bnx2x *bp = params->bp;
+
+       if (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) {
+               if (params->eee_mode & EEE_MODE_OUTPUT_TIME) {
+                       /* time value in eee_mode --> used directly*/
+                       eee_idle = params->eee_mode & EEE_MODE_TIMER_MASK;
+               } else {
+                       /* hsi value in eee_mode --> time */
+                       if (bnx2x_eee_nvram_to_time(params->eee_mode &
+                                                   EEE_MODE_NVRAM_MASK,
+                                                   &eee_idle))
+                               return 0;
+               }
+       } else {
+               /* hsi values in nvram --> time*/
+               eee_mode = ((REG_RD(bp, params->shmem_base +
+                                   offsetof(struct shmem_region, dev_info.
+                                   port_feature_config[params->port].
+                                   eee_power_mode)) &
+                            PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >>
+                           PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT);
+
+               if (bnx2x_eee_nvram_to_time(eee_mode, &eee_idle))
+                       return 0;
+       }
+
+       return eee_idle;
+}
+
+static int bnx2x_eee_set_timers(struct link_params *params,
+                                  struct link_vars *vars)
+{
+       u32 eee_idle = 0, eee_mode;
+       struct bnx2x *bp = params->bp;
+
+       eee_idle = bnx2x_eee_calc_timer(params);
+
+       if (eee_idle) {
+               REG_WR(bp, MISC_REG_CPMU_LP_IDLE_THR_P0 + (params->port << 2),
+                      eee_idle);
+       } else if ((params->eee_mode & EEE_MODE_ENABLE_LPI) &&
+                  (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) &&
+                  (params->eee_mode & EEE_MODE_OUTPUT_TIME)) {
+               DP(NETIF_MSG_LINK, "Error: Tx LPI is enabled with timer 0\n");
+               return -EINVAL;
+       }
+
+       vars->eee_status &= ~(SHMEM_EEE_TIMER_MASK | SHMEM_EEE_TIME_OUTPUT_BIT);
+       if (params->eee_mode & EEE_MODE_OUTPUT_TIME) {
+               /* eee_idle in 1u --> eee_status in 16u */
+               eee_idle >>= 4;
+               vars->eee_status |= (eee_idle & SHMEM_EEE_TIMER_MASK) |
+                                   SHMEM_EEE_TIME_OUTPUT_BIT;
+       } else {
+               if (bnx2x_eee_time_to_nvram(eee_idle, &eee_mode))
+                       return -EINVAL;
+               vars->eee_status |= eee_mode;
+       }
+
+       return 0;
+}
+
+static int bnx2x_eee_initial_config(struct link_params *params,
+                                    struct link_vars *vars, u8 mode)
+{
+       vars->eee_status |= ((u32) mode) << SHMEM_EEE_SUPPORTED_SHIFT;
+
+       /* Propogate params' bits --> vars (for migration exposure) */
+       if (params->eee_mode & EEE_MODE_ENABLE_LPI)
+               vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT;
+       else
+               vars->eee_status &= ~SHMEM_EEE_LPI_REQUESTED_BIT;
+
+       if (params->eee_mode & EEE_MODE_ADV_LPI)
+               vars->eee_status |= SHMEM_EEE_REQUESTED_BIT;
+       else
+               vars->eee_status &= ~SHMEM_EEE_REQUESTED_BIT;
+
+       return bnx2x_eee_set_timers(params, vars);
+}
+
+static int bnx2x_eee_disable(struct bnx2x_phy *phy,
+                               struct link_params *params,
+                               struct link_vars *vars)
+{
+       struct bnx2x *bp = params->bp;
+
+       /* Make Certain LPI is disabled */
+       REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), 0);
+
+       bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0x0);
+
+       vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
+
+       return 0;
+}
+
+static int bnx2x_eee_advertise(struct bnx2x_phy *phy,
+                                 struct link_params *params,
+                                 struct link_vars *vars, u8 modes)
+{
+       struct bnx2x *bp = params->bp;
+       u16 val = 0;
+
+       /* Mask events preventing LPI generation */
+       REG_WR(bp, MISC_REG_CPMU_LP_MASK_EXT_P0 + (params->port << 2), 0xfc20);
+
+       if (modes & SHMEM_EEE_10G_ADV) {
+               DP(NETIF_MSG_LINK, "Advertise 10GBase-T EEE\n");
+               val |= 0x8;
+       }
+       if (modes & SHMEM_EEE_1G_ADV) {
+               DP(NETIF_MSG_LINK, "Advertise 1GBase-T EEE\n");
+               val |= 0x4;
+       }
+
+       bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, val);
+
+       vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
+       vars->eee_status |= (modes << SHMEM_EEE_ADV_STATUS_SHIFT);
+
+       return 0;
+}
+
+static void bnx2x_update_mng_eee(struct link_params *params, u32 eee_status)
+{
+       struct bnx2x *bp = params->bp;
+
+       if (bnx2x_eee_has_cap(params))
+               REG_WR(bp, params->shmem2_base +
+                      offsetof(struct shmem2_region,
+                               eee_status[params->port]), eee_status);
+}
+
+static void bnx2x_eee_an_resolve(struct bnx2x_phy *phy,
+                                 struct link_params *params,
+                                 struct link_vars *vars)
+{
+       struct bnx2x *bp = params->bp;
+       u16 adv = 0, lp = 0;
+       u32 lp_adv = 0;
+       u8 neg = 0;
+
+       bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, &adv);
+       bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LP_EEE_ADV, &lp);
+
+       if (lp & 0x2) {
+               lp_adv |= SHMEM_EEE_100M_ADV;
+               if (adv & 0x2) {
+                       if (vars->line_speed == SPEED_100)
+                               neg = 1;
+                       DP(NETIF_MSG_LINK, "EEE negotiated - 100M\n");
+               }
+       }
+       if (lp & 0x14) {
+               lp_adv |= SHMEM_EEE_1G_ADV;
+               if (adv & 0x14) {
+                       if (vars->line_speed == SPEED_1000)
+                               neg = 1;
+                       DP(NETIF_MSG_LINK, "EEE negotiated - 1G\n");
+               }
+       }
+       if (lp & 0x68) {
+               lp_adv |= SHMEM_EEE_10G_ADV;
+               if (adv & 0x68) {
+                       if (vars->line_speed == SPEED_10000)
+                               neg = 1;
+                       DP(NETIF_MSG_LINK, "EEE negotiated - 10G\n");
+               }
+       }
+
+       vars->eee_status &= ~SHMEM_EEE_LP_ADV_STATUS_MASK;
+       vars->eee_status |= (lp_adv << SHMEM_EEE_LP_ADV_STATUS_SHIFT);
+
+       if (neg) {
+               DP(NETIF_MSG_LINK, "EEE is active\n");
+               vars->eee_status |= SHMEM_EEE_ACTIVE_BIT;
+       }
+
+}
+
 /******************************************************************/
 /*                     BSC access functions from E3              */
 /******************************************************************/
@@ -3752,6 +3904,19 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
  * init configuration, and set/clear SGMII flag. Internal
  * phy init is done purely in phy_init stage.
  */
+
+static void bnx2x_warpcore_set_lpi_passthrough(struct bnx2x_phy *phy,
+                                              struct link_params *params)
+{
+       struct bnx2x *bp = params->bp;
+
+       DP(NETIF_MSG_LINK, "Configure WC for LPI pass through\n");
+       bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+                        MDIO_WC_REG_EEE_COMBO_CONTROL0, 0x7c);
+       bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
+                                MDIO_WC_REG_DIGITAL4_MISC5, 0xc000);
+}
+
 static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
                                        struct link_params *params,
                                        struct link_vars *vars) {
@@ -4011,13 +4176,7 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
        bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
                                 MDIO_WC_REG_DIGITAL4_MISC3, 0x8080);
 
-       /* Enable LPI pass through */
-       DP(NETIF_MSG_LINK, "Configure WC for LPI pass through\n");
-       bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
-                        MDIO_WC_REG_EEE_COMBO_CONTROL0,
-                        0x7c);
-       bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
-                                MDIO_WC_REG_DIGITAL4_MISC5, 0xc000);
+       bnx2x_warpcore_set_lpi_passthrough(phy, params);
 
        /* 10G XFI Full Duplex */
        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
@@ -4114,6 +4273,8 @@ static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
                         MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13));
 
+       bnx2x_warpcore_set_lpi_passthrough(phy, params);
+
        if (always_autoneg || phy->req_line_speed == SPEED_AUTO_NEG) {
                /* SGMII Autoneg */
                bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
@@ -4716,6 +4877,10 @@ void bnx2x_link_status_update(struct link_params *params,
        vars->link_status = REG_RD(bp, params->shmem_base +
                                   offsetof(struct shmem_region,
                                            port_mb[port].link_status));
+       if (bnx2x_eee_has_cap(params))
+               vars->eee_status = REG_RD(bp, params->shmem2_base +
+                                         offsetof(struct shmem2_region,
+                                                  eee_status[params->port]));
 
        vars->phy_flags = PHY_XGXS_FLAG;
        bnx2x_sync_link(params, vars);
@@ -6536,7 +6701,6 @@ static int bnx2x_update_link_down(struct link_params *params,
                /* Prevent LPI Generation by chip */
                REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2),
                       0);
-               REG_WR(bp, MISC_REG_CPMU_LP_DR_ENABLE, 0);
                REG_WR(bp, MISC_REG_CPMU_LP_MASK_ENT_P0 + (params->port << 2),
                       0);
                vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
@@ -9883,39 +10047,6 @@ static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy,
        return 0;
 }
 
-static int bnx2x_8483x_eee_timers(struct link_params *params,
-                                  struct link_vars *vars)
-{
-       u32 eee_idle = 0, eee_mode;
-       struct bnx2x *bp = params->bp;
-
-       eee_idle = bnx2x_eee_calc_timer(params);
-
-       if (eee_idle) {
-               REG_WR(bp, MISC_REG_CPMU_LP_IDLE_THR_P0 + (params->port << 2),
-                      eee_idle);
-       } else if ((params->eee_mode & EEE_MODE_ENABLE_LPI) &&
-                  (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) &&
-                  (params->eee_mode & EEE_MODE_OUTPUT_TIME)) {
-               DP(NETIF_MSG_LINK, "Error: Tx LPI is enabled with timer 0\n");
-               return -EINVAL;
-       }
-
-       vars->eee_status &= ~(SHMEM_EEE_TIMER_MASK | SHMEM_EEE_TIME_OUTPUT_BIT);
-       if (params->eee_mode & EEE_MODE_OUTPUT_TIME) {
-               /* eee_idle in 1u --> eee_status in 16u */
-               eee_idle >>= 4;
-               vars->eee_status |= (eee_idle & SHMEM_EEE_TIMER_MASK) |
-                                   SHMEM_EEE_TIME_OUTPUT_BIT;
-       } else {
-               if (bnx2x_eee_time_to_nvram(eee_idle, &eee_mode))
-                       return -EINVAL;
-               vars->eee_status |= eee_mode;
-       }
-
-       return 0;
-}
-
 static int bnx2x_8483x_disable_eee(struct bnx2x_phy *phy,
                                   struct link_params *params,
                                   struct link_vars *vars)
@@ -9926,10 +10057,6 @@ static int bnx2x_8483x_disable_eee(struct bnx2x_phy *phy,
 
        DP(NETIF_MSG_LINK, "Don't Advertise 10GBase-T EEE\n");
 
-       /* Make Certain LPI is disabled */
-       REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), 0);
-       REG_WR(bp, MISC_REG_CPMU_LP_DR_ENABLE, 0);
-
        /* Prevent Phy from working in EEE and advertising it */
        rc = bnx2x_84833_cmd_hdlr(phy, params,
                PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1);
@@ -9938,10 +10065,7 @@ static int bnx2x_8483x_disable_eee(struct bnx2x_phy *phy,
                return rc;
        }
 
-       bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0);
-       vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
-
-       return 0;
+       return bnx2x_eee_disable(phy, params, vars);
 }
 
 static int bnx2x_8483x_enable_eee(struct bnx2x_phy *phy,
@@ -9952,8 +10076,6 @@ static int bnx2x_8483x_enable_eee(struct bnx2x_phy *phy,
        struct bnx2x *bp = params->bp;
        u16 cmd_args = 1;
 
-       DP(NETIF_MSG_LINK, "Advertise 10GBase-T EEE\n");
-
        rc = bnx2x_84833_cmd_hdlr(phy, params,
                PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1);
        if (rc) {
@@ -9961,15 +10083,7 @@ static int bnx2x_8483x_enable_eee(struct bnx2x_phy *phy,
                return rc;
        }
 
-       bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0x8);
-
-       /* Mask events preventing LPI generation */
-       REG_WR(bp, MISC_REG_CPMU_LP_MASK_EXT_P0 + (params->port << 2), 0xfc20);
-
-       vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
-       vars->eee_status |= (SHMEM_EEE_10G_ADV << SHMEM_EEE_ADV_STATUS_SHIFT);
-
-       return 0;
+       return bnx2x_eee_advertise(phy, params, vars, SHMEM_EEE_10G_ADV);
 }
 
 #define PHY84833_CONSTANT_LATENCY 1193
@@ -10101,22 +10215,10 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
                        MDIO_84833_TOP_CFG_FW_REV, &val);
 
        /* Configure EEE support */
-       if ((val >= MDIO_84833_TOP_CFG_FW_EEE) && bnx2x_eee_has_cap(params)) {
-               phy->flags |= FLAGS_EEE_10GBT;
-               vars->eee_status |= SHMEM_EEE_10G_ADV <<
-                                   SHMEM_EEE_SUPPORTED_SHIFT;
-               /* Propogate params' bits --> vars (for migration exposure) */
-               if (params->eee_mode & EEE_MODE_ENABLE_LPI)
-                       vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT;
-               else
-                       vars->eee_status &= ~SHMEM_EEE_LPI_REQUESTED_BIT;
-
-               if (params->eee_mode & EEE_MODE_ADV_LPI)
-                       vars->eee_status |= SHMEM_EEE_REQUESTED_BIT;
-               else
-                       vars->eee_status &= ~SHMEM_EEE_REQUESTED_BIT;
-
-               rc = bnx2x_8483x_eee_timers(params, vars);
+       if ((val >= MDIO_84833_TOP_CFG_FW_EEE) &&
+           (val != MDIO_84833_TOP_CFG_FW_NO_EEE) &&
+           bnx2x_eee_has_cap(params)) {
+               rc = bnx2x_eee_initial_config(params, vars, SHMEM_EEE_10G_ADV);
                if (rc) {
                        DP(NETIF_MSG_LINK, "Failed to configure EEE timers\n");
                        bnx2x_8483x_disable_eee(phy, params, vars);
@@ -10135,7 +10237,6 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
                        return rc;
                }
        } else {
-               phy->flags &= ~FLAGS_EEE_10GBT;
                vars->eee_status &= ~SHMEM_EEE_SUPPORTED_MASK;
        }
 
@@ -10274,29 +10375,8 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
                                LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
 
                /* Determine if EEE was negotiated */
-               if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
-                       u32 eee_shmem = 0;
-
-                       bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
-                                       MDIO_AN_REG_EEE_ADV, &val1);
-                       bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
-                                       MDIO_AN_REG_LP_EEE_ADV, &val2);
-                       if ((val1 & val2) & 0x8) {
-                               DP(NETIF_MSG_LINK, "EEE negotiated\n");
-                               vars->eee_status |= SHMEM_EEE_ACTIVE_BIT;
-                       }
-
-                       if (val2 & 0x12)
-                               eee_shmem |= SHMEM_EEE_100M_ADV;
-                       if (val2 & 0x4)
-                               eee_shmem |= SHMEM_EEE_1G_ADV;
-                       if (val2 & 0x68)
-                               eee_shmem |= SHMEM_EEE_10G_ADV;
-
-                       vars->eee_status &= ~SHMEM_EEE_LP_ADV_STATUS_MASK;
-                       vars->eee_status |= (eee_shmem <<
-                                            SHMEM_EEE_LP_ADV_STATUS_SHIFT);
-               }
+               if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
+                       bnx2x_eee_an_resolve(phy, params, vars);
        }
 
        return link_up;
@@ -10724,28 +10804,52 @@ static int bnx2x_54618se_config_init(struct bnx2x_phy *phy,
                DP(NETIF_MSG_LINK, "Setting 10M force\n");
        }
 
-       /* Check if we should turn on Auto-GrEEEn */
-       bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &temp);
-       if (temp == MDIO_REG_GPHY_ID_54618SE) {
-               if (params->feature_config_flags &
-                   FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
-                       temp = 6;
-                       DP(NETIF_MSG_LINK, "Enabling Auto-GrEEEn\n");
+       if ((phy->flags & FLAGS_EEE) && bnx2x_eee_has_cap(params)) {
+               int rc;
+
+               bnx2x_cl22_write(bp, phy, MDIO_REG_GPHY_EXP_ACCESS,
+                                MDIO_REG_GPHY_EXP_ACCESS_TOP |
+                                MDIO_REG_GPHY_EXP_TOP_2K_BUF);
+               bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, &temp);
+               temp &= 0xfffe;
+               bnx2x_cl22_write(bp, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, temp);
+
+               rc = bnx2x_eee_initial_config(params, vars, SHMEM_EEE_1G_ADV);
+               if (rc) {
+                       DP(NETIF_MSG_LINK, "Failed to configure EEE timers\n");
+                       bnx2x_eee_disable(phy, params, vars);
+               } else if ((params->eee_mode & EEE_MODE_ADV_LPI) &&
+                          (phy->req_duplex == DUPLEX_FULL) &&
+                          (bnx2x_eee_calc_timer(params) ||
+                           !(params->eee_mode & EEE_MODE_ENABLE_LPI))) {
+                       /* Need to advertise EEE only when requested,
+                        * and either no LPI assertion was requested,
+                        * or it was requested and a valid timer was set.
+                        * Also notice full duplex is required for EEE.
+                        */
+                       bnx2x_eee_advertise(phy, params, vars,
+                                           SHMEM_EEE_1G_ADV);
                } else {
-                       temp = 0;
-                       DP(NETIF_MSG_LINK, "Disabling Auto-GrEEEn\n");
+                       DP(NETIF_MSG_LINK, "Don't Advertise 1GBase-T EEE\n");
+                       bnx2x_eee_disable(phy, params, vars);
+               }
+       } else {
+               vars->eee_status &= ~SHMEM_EEE_1G_ADV <<
+                                   SHMEM_EEE_SUPPORTED_SHIFT;
+
+               if (phy->flags & FLAGS_EEE) {
+                       /* Handle legacy auto-grEEEn */
+                       if (params->feature_config_flags &
+                           FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
+                               temp = 6;
+                               DP(NETIF_MSG_LINK, "Enabling Auto-GrEEEn\n");
+                       } else {
+                               temp = 0;
+                               DP(NETIF_MSG_LINK, "Don't Adv. EEE\n");
+                       }
+                       bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
+                                        MDIO_AN_REG_EEE_ADV, temp);
                }
-               bnx2x_cl22_write(bp, phy,
-                                MDIO_REG_GPHY_CL45_ADDR_REG, MDIO_AN_DEVAD);
-               bnx2x_cl22_write(bp, phy,
-                                MDIO_REG_GPHY_CL45_DATA_REG,
-                                MDIO_REG_GPHY_EEE_ADV);
-               bnx2x_cl22_write(bp, phy,
-                                MDIO_REG_GPHY_CL45_ADDR_REG,
-                                (0x1 << 14) | MDIO_AN_DEVAD);
-               bnx2x_cl22_write(bp, phy,
-                                MDIO_REG_GPHY_CL45_DATA_REG,
-                                temp);
        }
 
        bnx2x_cl22_write(bp, phy,
@@ -10892,29 +10996,6 @@ static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy,
                DP(NETIF_MSG_LINK, "BCM54618SE: link speed is %d\n",
                           vars->line_speed);
 
-               /* Report whether EEE is resolved. */
-               bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &val);
-               if (val == MDIO_REG_GPHY_ID_54618SE) {
-                       if (vars->link_status &
-                           LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
-                               val = 0;
-                       else {
-                               bnx2x_cl22_write(bp, phy,
-                                       MDIO_REG_GPHY_CL45_ADDR_REG,
-                                       MDIO_AN_DEVAD);
-                               bnx2x_cl22_write(bp, phy,
-                                       MDIO_REG_GPHY_CL45_DATA_REG,
-                                       MDIO_REG_GPHY_EEE_RESOLVED);
-                               bnx2x_cl22_write(bp, phy,
-                                       MDIO_REG_GPHY_CL45_ADDR_REG,
-                                       (0x1 << 14) | MDIO_AN_DEVAD);
-                               bnx2x_cl22_read(bp, phy,
-                                       MDIO_REG_GPHY_CL45_DATA_REG,
-                                       &val);
-                       }
-                       DP(NETIF_MSG_LINK, "EEE resolution: 0x%x\n", val);
-               }
-
                bnx2x_ext_phy_resolve_fc(phy, params, vars);
 
                if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
@@ -10944,6 +11025,10 @@ static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy,
                        if (val & (1<<11))
                                vars->link_status |=
                                  LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
+
+                       if ((phy->flags & FLAGS_EEE) &&
+                           bnx2x_eee_has_cap(params))
+                               bnx2x_eee_an_resolve(phy, params, vars);
                }
        }
        return link_up;
@@ -11551,8 +11636,7 @@ static struct bnx2x_phy phy_84833 = {
        .def_md_devad   = 0,
        .flags          = (FLAGS_FAN_FAILURE_DET_REQ |
                           FLAGS_REARM_LATCH_SIGNAL |
-                          FLAGS_TX_ERROR_CHECK |
-                          FLAGS_EEE_10GBT),
+                          FLAGS_TX_ERROR_CHECK),
        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
        .mdio_ctrl      = 0,
@@ -11858,6 +11942,8 @@ static int bnx2x_populate_ext_phy(struct bnx2x *bp,
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616:
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE:
                *phy = phy_54618se;
+               if (phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
+                       phy->flags |= FLAGS_EEE;
                break;
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
                *phy = phy_7101;
index 51cac8130051e27a0994c288712346698280d740..360ecf9e07398a603197bbbe49144f12cb5b544b 100644 (file)
@@ -155,7 +155,7 @@ struct bnx2x_phy {
 #define FLAGS_DUMMY_READ               (1<<9)
 #define FLAGS_MDC_MDIO_WA_B0           (1<<10)
 #define FLAGS_TX_ERROR_CHECK           (1<<12)
-#define FLAGS_EEE_10GBT                        (1<<13)
+#define FLAGS_EEE                      (1<<13)
 
        /* preemphasis values for the rx side */
        u16 rx_preemphasis[4];
index 28a0bcfe61ff9a4224d5b1f3442400a363bce79b..1b1999d34c7180f41649b606695ecccfbcb237c5 100644 (file)
 #define UMAC_COMMAND_CONFIG_REG_SW_RESET                        (0x1<<13)
 #define UMAC_COMMAND_CONFIG_REG_TX_ENA                          (0x1<<0)
 #define UMAC_REG_COMMAND_CONFIG                                         0x8
+/* [RW 16] This is the duration for which MAC must wait to go back to ACTIVE
+ * state from LPI state when it receives packet for transmission. The
+ * decrement unit is 1 micro-second. */
+#define UMAC_REG_EEE_WAKE_TIMER                                         0x6c
 /* [RW 32] Register Bit 0 refers to Bit 16 of the MAC address; Bit 1 refers
  * to bit 17 of the MAC address etc. */
 #define UMAC_REG_MAC_ADDR0                                      0xc
 /* [RW 14] Defines a 14-Bit maximum frame length used by the MAC receive
  * logic to check frames. */
 #define UMAC_REG_MAXFR                                          0x14
+#define UMAC_REG_UMAC_EEE_CTRL                                  0x64
+#define UMAC_UMAC_EEE_CTRL_REG_EEE_EN                           (0x1<<3)
 /* [RW 8] The event id for aggregated interrupt 0 */
 #define USDM_REG_AGG_INT_EVENT_0                                0xc4038
 #define USDM_REG_AGG_INT_EVENT_1                                0xc403c
@@ -6992,6 +6998,7 @@ Theotherbitsarereservedandshouldbezero*/
 /* BCM84833 only */
 #define MDIO_84833_TOP_CFG_FW_REV                      0x400f
 #define MDIO_84833_TOP_CFG_FW_EEE              0x10b1
+#define MDIO_84833_TOP_CFG_FW_NO_EEE           0x1f81
 #define MDIO_84833_TOP_CFG_XGPHY_STRAP1                        0x401a
 #define MDIO_84833_SUPER_ISOLATE               0x8000
 /* These are mailbox register set used by 84833. */
@@ -7160,10 +7167,11 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_REG_GPHY_ID_54618SE               0x5cd5
 #define MDIO_REG_GPHY_CL45_ADDR_REG                    0xd
 #define MDIO_REG_GPHY_CL45_DATA_REG                    0xe
-#define MDIO_REG_GPHY_EEE_ADV                  0x3c
-#define MDIO_REG_GPHY_EEE_1G           (0x1 << 2)
-#define MDIO_REG_GPHY_EEE_100          (0x1 << 1)
 #define MDIO_REG_GPHY_EEE_RESOLVED             0x803e
+#define MDIO_REG_GPHY_EXP_ACCESS_GATE                  0x15
+#define MDIO_REG_GPHY_EXP_ACCESS                       0x17
+#define MDIO_REG_GPHY_EXP_ACCESS_TOP           0xd00
+#define MDIO_REG_GPHY_EXP_TOP_2K_BUF           0x40
 #define MDIO_REG_GPHY_AUX_STATUS                       0x19
 #define MDIO_REG_INTR_STATUS                           0x1a
 #define MDIO_REG_INTR_MASK                             0x1b
index 62f754bd0dfe65704a1af826a754a720dc8cfd43..5a5fbf57c4b4fdce4d15000113ef9987e67ec5f5 100644 (file)
@@ -229,8 +229,7 @@ static inline int bnx2x_exe_queue_step(struct bnx2x *bp,
                         */
                        list_add_tail(&spacer.link, &o->pending_comp);
                        mb();
-                       list_del(&elem->link);
-                       list_add_tail(&elem->link, &o->pending_comp);
+                       list_move_tail(&elem->link, &o->pending_comp);
                        list_del(&spacer.link);
                } else
                        break;
index 332db64dd5bea11eed0cf878565c5c2e573f5c3e..ab00b352f4a90dd70b500750ad774b59359f2ad2 100644 (file)
@@ -39,14 +39,39 @@ static inline long bnx2x_hilo(u32 *hiref)
 #endif
 }
 
-static u16 bnx2x_get_port_stats_dma_len(struct bnx2x *bp)
+static inline u16 bnx2x_get_port_stats_dma_len(struct bnx2x *bp)
 {
-       u16 res = sizeof(struct host_port_stats) >> 2;
+       u16 res = 0;
 
-       /* if PFC stats are not supported by the MFW, don't DMA them */
-       if (!(bp->flags &  BC_SUPPORTS_PFC_STATS))
-               res -= (sizeof(u32)*4) >> 2;
+       /* 'newest' convention - shmem2 cotains the size of the port stats */
+       if (SHMEM2_HAS(bp, sizeof_port_stats)) {
+               u32 size = SHMEM2_RD(bp, sizeof_port_stats);
+               if (size)
+                       res = size;
 
+               /* prevent newer BC from causing buffer overflow */
+               if (res > sizeof(struct host_port_stats))
+                       res = sizeof(struct host_port_stats);
+       }
+
+       /* Older convention - all BCs support the port stats' fields up until
+        * the 'not_used' field
+        */
+       if (!res) {
+               res = offsetof(struct host_port_stats, not_used) + 4;
+
+               /* if PFC stats are supported by the MFW, DMA them as well */
+               if (bp->flags & BC_SUPPORTS_PFC_STATS) {
+                       res += offsetof(struct host_port_stats,
+                                       pfc_frames_rx_lo) -
+                              offsetof(struct host_port_stats,
+                                       pfc_frames_tx_hi) + 4 ;
+               }
+       }
+
+       res >>= 2;
+
+       WARN_ON(res > 2 * DMAE_LEN32_RD_MAX);
        return res;
 }
 
index 3b4fc61f24cfe1cb047dbbd16e86d7180a102046..2107d79d69b37ca3f6740735e0971f31c0e3bbe0 100644 (file)
@@ -823,10 +823,8 @@ static void cnic_free_context(struct cnic_dev *dev)
        }
 }
 
-static void __cnic_free_uio(struct cnic_uio_dev *udev)
+static void __cnic_free_uio_rings(struct cnic_uio_dev *udev)
 {
-       uio_unregister_device(&udev->cnic_uinfo);
-
        if (udev->l2_buf) {
                dma_free_coherent(&udev->pdev->dev, udev->l2_buf_size,
                                  udev->l2_buf, udev->l2_buf_map);
@@ -839,6 +837,14 @@ static void __cnic_free_uio(struct cnic_uio_dev *udev)
                udev->l2_ring = NULL;
        }
 
+}
+
+static void __cnic_free_uio(struct cnic_uio_dev *udev)
+{
+       uio_unregister_device(&udev->cnic_uinfo);
+
+       __cnic_free_uio_rings(udev);
+
        pci_dev_put(udev->pdev);
        kfree(udev);
 }
@@ -862,6 +868,8 @@ static void cnic_free_resc(struct cnic_dev *dev)
        if (udev) {
                udev->dev = NULL;
                cp->udev = NULL;
+               if (udev->uio_dev == -1)
+                       __cnic_free_uio_rings(udev);
        }
 
        cnic_free_context(dev);
@@ -996,6 +1004,34 @@ static int cnic_alloc_kcq(struct cnic_dev *dev, struct kcq_info *info,
        return 0;
 }
 
+static int __cnic_alloc_uio_rings(struct cnic_uio_dev *udev, int pages)
+{
+       struct cnic_local *cp = udev->dev->cnic_priv;
+
+       if (udev->l2_ring)
+               return 0;
+
+       udev->l2_ring_size = pages * BCM_PAGE_SIZE;
+       udev->l2_ring = dma_alloc_coherent(&udev->pdev->dev, udev->l2_ring_size,
+                                          &udev->l2_ring_map,
+                                          GFP_KERNEL | __GFP_COMP);
+       if (!udev->l2_ring)
+               return -ENOMEM;
+
+       udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size;
+       udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size);
+       udev->l2_buf = dma_alloc_coherent(&udev->pdev->dev, udev->l2_buf_size,
+                                         &udev->l2_buf_map,
+                                         GFP_KERNEL | __GFP_COMP);
+       if (!udev->l2_buf) {
+               __cnic_free_uio_rings(udev);
+               return -ENOMEM;
+       }
+
+       return 0;
+
+}
+
 static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
 {
        struct cnic_local *cp = dev->cnic_priv;
@@ -1005,6 +1041,11 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
        list_for_each_entry(udev, &cnic_udev_list, list) {
                if (udev->pdev == dev->pcidev) {
                        udev->dev = dev;
+                       if (__cnic_alloc_uio_rings(udev, pages)) {
+                               udev->dev = NULL;
+                               read_unlock(&cnic_dev_lock);
+                               return -ENOMEM;
+                       }
                        cp->udev = udev;
                        read_unlock(&cnic_dev_lock);
                        return 0;
@@ -1020,20 +1061,9 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
 
        udev->dev = dev;
        udev->pdev = dev->pcidev;
-       udev->l2_ring_size = pages * BCM_PAGE_SIZE;
-       udev->l2_ring = dma_alloc_coherent(&udev->pdev->dev, udev->l2_ring_size,
-                                          &udev->l2_ring_map,
-                                          GFP_KERNEL | __GFP_COMP);
-       if (!udev->l2_ring)
-               goto err_udev;
 
-       udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size;
-       udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size);
-       udev->l2_buf = dma_alloc_coherent(&udev->pdev->dev, udev->l2_buf_size,
-                                         &udev->l2_buf_map,
-                                         GFP_KERNEL | __GFP_COMP);
-       if (!udev->l2_buf)
-               goto err_dma;
+       if (__cnic_alloc_uio_rings(udev, pages))
+               goto err_udev;
 
        write_lock(&cnic_dev_lock);
        list_add(&udev->list, &cnic_udev_list);
@@ -1044,9 +1074,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
        cp->udev = udev;
 
        return 0;
- err_dma:
-       dma_free_coherent(&udev->pdev->dev, udev->l2_ring_size,
-                         udev->l2_ring, udev->l2_ring_map);
+
  err_udev:
        kfree(udev);
        return -ENOMEM;
@@ -1260,7 +1288,7 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
        if (ret)
                goto error;
 
-       if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) {
+       if (CNIC_SUPPORTS_FCOE(cp)) {
                ret = cnic_alloc_kcq(dev, &cp->kcq2, true);
                if (ret)
                        goto error;
@@ -1275,6 +1303,9 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
        if (ret)
                goto error;
 
+       if (cp->ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI)
+               return 0;
+
        cp->bnx2x_def_status_blk = cp->ethdev->irq_arr[1].status_blk;
 
        cp->l2_rx_ring_size = 15;
@@ -3050,6 +3081,22 @@ static void cnic_ack_bnx2x_e2_msix(struct cnic_dev *dev)
                        IGU_INT_DISABLE, 0);
 }
 
+static void cnic_arm_bnx2x_msix(struct cnic_dev *dev, u32 idx)
+{
+       struct cnic_local *cp = dev->cnic_priv;
+
+       cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, CSTORM_ID, idx,
+                          IGU_INT_ENABLE, 1);
+}
+
+static void cnic_arm_bnx2x_e2_msix(struct cnic_dev *dev, u32 idx)
+{
+       struct cnic_local *cp = dev->cnic_priv;
+
+       cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF, idx,
+                       IGU_INT_ENABLE, 1);
+}
+
 static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info)
 {
        u32 last_status = *info->status_idx_ptr;
@@ -3086,9 +3133,8 @@ static void cnic_service_bnx2x_bh(unsigned long data)
                CNIC_WR16(dev, cp->kcq1.io_addr,
                          cp->kcq1.sw_prod_idx + MAX_KCQ_IDX);
 
-               if (!BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) {
-                       cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID,
-                                          status_idx, IGU_INT_ENABLE, 1);
+               if (cp->ethdev->drv_state & CNIC_DRV_STATE_NO_FCOE) {
+                       cp->arm_int(dev, status_idx);
                        break;
                }
 
@@ -5308,7 +5354,7 @@ static void cnic_stop_hw(struct cnic_dev *dev)
                /* Need to wait for the ring shutdown event to complete
                 * before clearing the CNIC_UP flag.
                 */
-               while (cp->udev->uio_dev != -1 && i < 15) {
+               while (cp->udev && cp->udev->uio_dev != -1 && i < 15) {
                        msleep(100);
                        i++;
                }
@@ -5473,8 +5519,7 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev)
 
        if (!(ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI))
                cdev->max_iscsi_conn = ethdev->max_iscsi_conn;
-       if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id) &&
-           !(ethdev->drv_state & CNIC_DRV_STATE_NO_FCOE))
+       if (CNIC_SUPPORTS_FCOE(cp))
                cdev->max_fcoe_conn = ethdev->max_fcoe_conn;
 
        if (cdev->max_fcoe_conn > BNX2X_FCOE_NUM_CONNECTIONS)
@@ -5492,10 +5537,13 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev)
        cp->stop_cm = cnic_cm_stop_bnx2x_hw;
        cp->enable_int = cnic_enable_bnx2x_int;
        cp->disable_int_sync = cnic_disable_bnx2x_int_sync;
-       if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id))
+       if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) {
                cp->ack_int = cnic_ack_bnx2x_e2_msix;
-       else
+               cp->arm_int = cnic_arm_bnx2x_e2_msix;
+       } else {
                cp->ack_int = cnic_ack_bnx2x_msix;
+               cp->arm_int = cnic_arm_bnx2x_msix;
+       }
        cp->close_conn = cnic_close_bnx2x_conn;
        return cdev;
 }
index 30328097f516375ee7db7fe9179e178c71cf3375..148604c3fa0c79c51bf0fd1dc75edc3f7598c670 100644 (file)
@@ -334,6 +334,7 @@ struct cnic_local {
        void                    (*enable_int)(struct cnic_dev *);
        void                    (*disable_int_sync)(struct cnic_dev *);
        void                    (*ack_int)(struct cnic_dev *);
+       void                    (*arm_int)(struct cnic_dev *, u32 index);
        void                    (*close_conn)(struct cnic_sock *, u32 opcode);
 };
 
@@ -474,6 +475,10 @@ struct bnx2x_bd_chain_next {
          MAX_STAT_COUNTER_ID_E1))
 #endif
 
+#define CNIC_SUPPORTS_FCOE(cp)                                 \
+       (BNX2X_CHIP_IS_E2_PLUS((cp)->chip_id) &&                \
+        !((cp)->ethdev->drv_state & CNIC_DRV_STATE_NO_FCOE))
+
 #define CNIC_RAMROD_TMO                        (HZ / 4)
 
 #endif
index 5cb88881bba1134776731b7f438d876ed47dc441..2e92c348083e04d955ea6702092dd3c2c4d90e0c 100644 (file)
@@ -14,8 +14,8 @@
 
 #include "bnx2x/bnx2x_mfw_req.h"
 
-#define CNIC_MODULE_VERSION    "2.5.12"
-#define CNIC_MODULE_RELDATE    "June 29, 2012"
+#define CNIC_MODULE_VERSION    "2.5.13"
+#define CNIC_MODULE_RELDATE    "Sep 07, 2012"
 
 #define CNIC_ULP_RDMA          0
 #define CNIC_ULP_ISCSI         1
index 5ed49af23d6ae37f5f7f7136412c9c0f20ac3e56..34d510dd56a8851099bbf614580924213e2f7481 100644 (file)
@@ -2470,8 +2470,8 @@ int cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx,
                else
                        delta = size - hw_pidx + pidx;
                wmb();
-               t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL),
-                            V_QID(qid) | V_PIDX(delta));
+               t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL),
+                            QID(qid) | PIDX(delta));
        }
 out:
        return ret;
@@ -2579,8 +2579,8 @@ static void sync_txq_pidx(struct adapter *adap, struct sge_txq *q)
                else
                        delta = q->size - hw_pidx + q->db_pidx;
                wmb();
-               t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL),
-                               V_QID(q->cntxt_id) | V_PIDX(delta));
+               t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL),
+                            QID(q->cntxt_id) | PIDX(delta));
        }
 out:
        q->db_disabled = 0;
@@ -2617,9 +2617,9 @@ static void process_db_full(struct work_struct *work)
 
        notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL);
        drain_db_fifo(adap, dbfifo_drain_delay);
-       t4_set_reg_field(adap, A_SGE_INT_ENABLE3,
-                       F_DBFIFO_HP_INT | F_DBFIFO_LP_INT,
-                       F_DBFIFO_HP_INT | F_DBFIFO_LP_INT);
+       t4_set_reg_field(adap, SGE_INT_ENABLE3,
+                        DBFIFO_HP_INT | DBFIFO_LP_INT,
+                        DBFIFO_HP_INT | DBFIFO_LP_INT);
        notify_rdma_uld(adap, CXGB4_CONTROL_DB_EMPTY);
 }
 
@@ -2639,8 +2639,8 @@ static void process_db_drop(struct work_struct *work)
 
 void t4_db_full(struct adapter *adap)
 {
-       t4_set_reg_field(adap, A_SGE_INT_ENABLE3,
-                       F_DBFIFO_HP_INT | F_DBFIFO_LP_INT, 0);
+       t4_set_reg_field(adap, SGE_INT_ENABLE3,
+                        DBFIFO_HP_INT | DBFIFO_LP_INT, 0);
        queue_work(workq, &adap->db_full_task);
 }
 
index d49933ed551f7a4fca4d6b71f0528aaf9f6a80d6..1fde57d453182a63ff2f32b9e4083c0f6fe33600 100644 (file)
@@ -769,8 +769,8 @@ static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q, int n)
        wmb();            /* write descriptors before telling HW */
        spin_lock(&q->db_lock);
        if (!q->db_disabled) {
-               t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL),
-                            V_QID(q->cntxt_id) | V_PIDX(n));
+               t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL),
+                            QID(q->cntxt_id) | PIDX(n));
        }
        q->db_pidx = q->pidx;
        spin_unlock(&q->db_lock);
index fa947dfa4c304c5051763ae240a19f33b95dee3d..8e988d699d05788b66d7adf5e1c795e1fee0428b 100644 (file)
@@ -1018,9 +1018,9 @@ static void sge_intr_handler(struct adapter *adapter)
                { ERR_INVALID_CIDX_INC,
                  "SGE GTS CIDX increment too large", -1, 0 },
                { ERR_CPL_OPCODE_0, "SGE received 0-length CPL", -1, 0 },
-               { F_DBFIFO_LP_INT, NULL, -1, 0, t4_db_full },
-               { F_DBFIFO_HP_INT, NULL, -1, 0, t4_db_full },
-               { F_ERR_DROPPED_DB, NULL, -1, 0, t4_db_dropped },
+               { DBFIFO_LP_INT, NULL, -1, 0, t4_db_full },
+               { DBFIFO_HP_INT, NULL, -1, 0, t4_db_full },
+               { ERR_DROPPED_DB, NULL, -1, 0, t4_db_dropped },
                { ERR_DATA_CPL_ON_HIGH_QID1 | ERR_DATA_CPL_ON_HIGH_QID0,
                  "SGE IQID > 1023 received CPL for FL", -1, 0 },
                { ERR_BAD_DB_PIDX3, "SGE DBP 3 pidx increment too large", -1,
@@ -1520,7 +1520,7 @@ void t4_intr_enable(struct adapter *adapter)
                     ERR_BAD_DB_PIDX2 | ERR_BAD_DB_PIDX1 |
                     ERR_BAD_DB_PIDX0 | ERR_ING_CTXT_PRIO |
                     ERR_EGR_CTXT_PRIO | INGRESS_SIZE_ERR |
-                    F_DBFIFO_HP_INT | F_DBFIFO_LP_INT |
+                    DBFIFO_HP_INT | DBFIFO_LP_INT |
                     EGRESS_SIZE_ERR);
        t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE), PF_INTR_MASK);
        t4_set_reg_field(adapter, PL_INT_MAP0, 0, 1 << pf);
@@ -2033,8 +2033,8 @@ int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len)
        if ((addr & 3) || (len + off) > MEMWIN0_APERTURE)
                return -EINVAL;
 
-       t4_write_reg(adap, A_PCIE_MEM_ACCESS_OFFSET, addr & ~15);
-       t4_read_reg(adap, A_PCIE_MEM_ACCESS_OFFSET);
+       t4_write_reg(adap, PCIE_MEM_ACCESS_OFFSET, addr & ~15);
+       t4_read_reg(adap, PCIE_MEM_ACCESS_OFFSET);
 
        for (i = 0; i < len; i += 4)
                *data++ = t4_read_reg(adap, (MEMWIN0_BASE + off + i));
index 111fc323f155c4dbab831ac1fab85e2228a3bb6a..8e814bc46822ebed675d8559c6042ff480cac812 100644 (file)
 #define SGE_DEBUG_DATA_LOW 0x10d4
 #define SGE_INGRESS_QUEUES_PER_PAGE_PF 0x10f4
 
-#define S_LP_INT_THRESH    12
-#define V_LP_INT_THRESH(x) ((x) << S_LP_INT_THRESH)
 #define S_HP_INT_THRESH    28
+#define M_HP_INT_THRESH 0xfU
 #define V_HP_INT_THRESH(x) ((x) << S_HP_INT_THRESH)
+#define M_HP_COUNT 0x7ffU
+#define S_HP_COUNT 16
+#define G_HP_COUNT(x) (((x) >> S_HP_COUNT) & M_HP_COUNT)
+#define S_LP_INT_THRESH    12
+#define M_LP_INT_THRESH 0xfU
+#define V_LP_INT_THRESH(x) ((x) << S_LP_INT_THRESH)
+#define M_LP_COUNT 0x7ffU
+#define S_LP_COUNT 0
+#define G_LP_COUNT(x) (((x) >> S_LP_COUNT) & M_LP_COUNT)
 #define A_SGE_DBFIFO_STATUS 0x10a4
 
 #define S_ENABLE_DROP    13
 #define V_ENABLE_DROP(x) ((x) << S_ENABLE_DROP)
 #define F_ENABLE_DROP    V_ENABLE_DROP(1U)
-#define A_SGE_DOORBELL_CONTROL 0x10a8
-
-#define A_SGE_CTXT_CMD 0x11fc
-#define A_SGE_DBQ_CTXT_BADDR 0x1084
-
-#define A_SGE_PF_KDOORBELL 0x0
-
-#define S_QID 15
-#define V_QID(x) ((x) << S_QID)
-
-#define S_PIDX 0
-#define V_PIDX(x) ((x) << S_PIDX)
-
-#define M_LP_COUNT 0x7ffU
-#define S_LP_COUNT 0
-#define G_LP_COUNT(x) (((x) >> S_LP_COUNT) & M_LP_COUNT)
-
-#define M_HP_COUNT 0x7ffU
-#define S_HP_COUNT 16
-#define G_HP_COUNT(x) (((x) >> S_HP_COUNT) & M_HP_COUNT)
-
-#define A_SGE_INT_ENABLE3 0x1040
-
-#define S_DBFIFO_HP_INT 8
-#define V_DBFIFO_HP_INT(x) ((x) << S_DBFIFO_HP_INT)
-#define F_DBFIFO_HP_INT V_DBFIFO_HP_INT(1U)
-
-#define S_DBFIFO_LP_INT 7
-#define V_DBFIFO_LP_INT(x) ((x) << S_DBFIFO_LP_INT)
-#define F_DBFIFO_LP_INT V_DBFIFO_LP_INT(1U)
-
 #define S_DROPPED_DB 0
 #define V_DROPPED_DB(x) ((x) << S_DROPPED_DB)
 #define F_DROPPED_DB V_DROPPED_DB(1U)
+#define A_SGE_DOORBELL_CONTROL 0x10a8
 
-#define S_ERR_DROPPED_DB 18
-#define V_ERR_DROPPED_DB(x) ((x) << S_ERR_DROPPED_DB)
-#define F_ERR_DROPPED_DB V_ERR_DROPPED_DB(1U)
-
-#define A_PCIE_MEM_ACCESS_OFFSET 0x306c
-
-#define M_HP_INT_THRESH 0xfU
-#define M_LP_INT_THRESH 0xfU
+#define A_SGE_CTXT_CMD 0x11fc
+#define A_SGE_DBQ_CTXT_BADDR 0x1084
 
 #define PCIE_PF_CLI 0x44
 #define PCIE_INT_CAUSE 0x3004
index 111dc8813f68135fb332adcc441878745f9fd70d..84379f4fe83711f2eb347249b5118bb5132c57b9 100644 (file)
@@ -20,6 +20,7 @@
 #include "be.h"
 #include "be_cmds.h"
 #include <asm/div64.h>
+#include <linux/aer.h>
 
 MODULE_VERSION(DRV_VER);
 MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@ -3551,6 +3552,8 @@ static void __devexit be_remove(struct pci_dev *pdev)
 
        be_ctrl_cleanup(adapter);
 
+       pci_disable_pcie_error_reporting(pdev);
+
        pci_set_drvdata(pdev, NULL);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
@@ -3846,6 +3849,10 @@ static int __devinit be_probe(struct pci_dev *pdev,
                }
        }
 
+       status = pci_enable_pcie_error_reporting(pdev);
+       if (status)
+               dev_err(&pdev->dev, "Could not use PCIe error reporting\n");
+
        status = be_ctrl_init(adapter);
        if (status)
                goto free_netdev;
@@ -4068,6 +4075,7 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
        if (status)
                return PCI_ERS_RESULT_DISCONNECT;
 
+       pci_cleanup_aer_uncorrect_error_status(pdev);
        return PCI_ERS_RESULT_RECOVERED;
 }
 
index 9e572dd29ab288e98bd72c4859f16fbf839c9c3b..0c9f62caa8fa505a9fd958e6b30d65efe364e4b4 100644 (file)
@@ -131,9 +131,9 @@ struct vf_data_storage {
 #define MAXIMUM_ETHERNET_VLAN_SIZE 1522
 
 /* Supported Rx Buffer Sizes */
-#define IGB_RXBUFFER_512   512
+#define IGB_RXBUFFER_256   256
 #define IGB_RXBUFFER_16384 16384
-#define IGB_RX_HDR_LEN     IGB_RXBUFFER_512
+#define IGB_RX_HDR_LEN     IGB_RXBUFFER_256
 
 /* How many Tx Descriptors do we need to call netif_wake_queue ? */
 #define IGB_TX_QUEUE_WAKE      16
index be02168f1308872fa49d86dfcad77b0ab5f91246..a2944412a55ec8e316afdff9ee48b71eb2ae1730 100644 (file)
@@ -148,9 +148,9 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
                                   SUPPORTED_100baseT_Full |
                                   SUPPORTED_1000baseT_Full|
                                   SUPPORTED_Autoneg |
-                                  SUPPORTED_TP);
-               ecmd->advertising = (ADVERTISED_TP |
-                                    ADVERTISED_Pause);
+                                  SUPPORTED_TP |
+                                  SUPPORTED_Pause);
+               ecmd->advertising = ADVERTISED_TP;
 
                if (hw->mac.autoneg == 1) {
                        ecmd->advertising |= ADVERTISED_Autoneg;
@@ -158,6 +158,21 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
                        ecmd->advertising |= hw->phy.autoneg_advertised;
                }
 
+               if (hw->mac.autoneg != 1)
+                       ecmd->advertising &= ~(ADVERTISED_Pause |
+                                              ADVERTISED_Asym_Pause);
+
+               if (hw->fc.requested_mode == e1000_fc_full)
+                       ecmd->advertising |= ADVERTISED_Pause;
+               else if (hw->fc.requested_mode == e1000_fc_rx_pause)
+                       ecmd->advertising |= (ADVERTISED_Pause |
+                                             ADVERTISED_Asym_Pause);
+               else if (hw->fc.requested_mode == e1000_fc_tx_pause)
+                       ecmd->advertising |=  ADVERTISED_Asym_Pause;
+               else
+                       ecmd->advertising &= ~(ADVERTISED_Pause |
+                                              ADVERTISED_Asym_Pause);
+
                ecmd->port = PORT_TP;
                ecmd->phy_address = hw->phy.addr;
        } else {
@@ -1511,33 +1526,22 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
        u32 ctrl_reg = 0;
-       u16 phy_reg = 0;
 
        hw->mac.autoneg = false;
 
-       switch (hw->phy.type) {
-       case e1000_phy_m88:
-               /* Auto-MDI/MDIX Off */
-               igb_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, 0x0808);
-               /* reset to update Auto-MDI/MDIX */
-               igb_write_phy_reg(hw, PHY_CONTROL, 0x9140);
-               /* autoneg off */
-               igb_write_phy_reg(hw, PHY_CONTROL, 0x8140);
-               break;
-       case e1000_phy_82580:
-               /* enable MII loopback */
-               igb_write_phy_reg(hw, I82580_PHY_LBK_CTRL, 0x8041);
-               break;
-       case e1000_phy_i210:
-               /* set loopback speed in PHY */
-               igb_read_phy_reg(hw, (GS40G_PAGE_SELECT & GS40G_PAGE_2),
-                                       &phy_reg);
-               phy_reg |= GS40G_MAC_SPEED_1G;
-               igb_write_phy_reg(hw, (GS40G_PAGE_SELECT & GS40G_PAGE_2),
-                                       phy_reg);
-               ctrl_reg = rd32(E1000_CTRL_EXT);
-       default:
-               break;
+       if (hw->phy.type == e1000_phy_m88) {
+               if (hw->phy.id != I210_I_PHY_ID) {
+                       /* Auto-MDI/MDIX Off */
+                       igb_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, 0x0808);
+                       /* reset to update Auto-MDI/MDIX */
+                       igb_write_phy_reg(hw, PHY_CONTROL, 0x9140);
+                       /* autoneg off */
+                       igb_write_phy_reg(hw, PHY_CONTROL, 0x8140);
+               } else {
+                       /* force 1000, set loopback  */
+                       igb_write_phy_reg(hw, I347AT4_PAGE_SELECT, 0);
+                       igb_write_phy_reg(hw, PHY_CONTROL, 0x4140);
+               }
        }
 
        /* add small delay to avoid loopback test failure */
@@ -1555,7 +1559,7 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter)
                     E1000_CTRL_FD |     /* Force Duplex to FULL */
                     E1000_CTRL_SLU);    /* Set link up enable bit */
 
-       if ((hw->phy.type == e1000_phy_m88) || (hw->phy.type == e1000_phy_i210))
+       if (hw->phy.type == e1000_phy_m88)
                ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */
 
        wr32(E1000_CTRL, ctrl_reg);
@@ -1563,11 +1567,10 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter)
        /* Disable the receiver on the PHY so when a cable is plugged in, the
         * PHY does not begin to autoneg when a cable is reconnected to the NIC.
         */
-       if ((hw->phy.type == e1000_phy_m88) || (hw->phy.type == e1000_phy_i210))
+       if (hw->phy.type == e1000_phy_m88)
                igb_phy_disable_receiver(adapter);
 
-       udelay(500);
-
+       mdelay(500);
        return 0;
 }
 
@@ -1827,13 +1830,6 @@ static int igb_loopback_test(struct igb_adapter *adapter, u64 *data)
                *data = 0;
                goto out;
        }
-       if ((adapter->hw.mac.type == e1000_i210)
-               || (adapter->hw.mac.type == e1000_i211)) {
-               dev_err(&adapter->pdev->dev,
-                       "Loopback test not supported on this part at this time.\n");
-               *data = 0;
-               goto out;
-       }
        *data = igb_setup_desc_rings(adapter);
        if (*data)
                goto out;
index fa0d6e1561c14c06fc546918e4f653bcfac14774..1cbb34f507c98b96e4cd9a28c17babc6f51b726a 100644 (file)
@@ -7169,11 +7169,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
                goto err_ioremap;
        }
 
-       for (i = 1; i <= 5; i++) {
-               if (pci_resource_len(pdev, i) == 0)
-                       continue;
-       }
-
        netdev->netdev_ops = &ixgbe_netdev_ops;
        ixgbe_set_ethtool_ops(netdev);
        netdev->watchdog_timeo = 5 * HZ;
index 1fc4eefc20edb680991b4ef2d3e2d4f1caab49b9..08ae4655423a6b8f7deeee92d588fa38f0ec5cf4 100644 (file)
@@ -34,3 +34,14 @@ config IEEE802154_AT86RF230
         depends on IEEE802154_DRIVERS && MAC802154
         tristate "AT86RF230/231 transceiver driver"
         depends on SPI
+
+config IEEE802154_MRF24J40
+       tristate "Microchip MRF24J40 transceiver driver"
+       depends on IEEE802154_DRIVERS && MAC802154
+       depends on SPI
+       ---help---
+         Say Y here to enable the MRF24J20 SPI 802.15.4 wireless
+         controller.
+
+         This driver can also be built as a module. To do so, say M here.
+         the module will be called 'mrf24j40'.
index 4f4371d3aa7d7f87220fea548651933c1a727333..abb0c08decb0f89a623921bab13d223f4acb56bd 100644 (file)
@@ -1,3 +1,4 @@
 obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o
 obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o
 obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o
+obj-$(CONFIG_IEEE802154_MRF24J40) += mrf24j40.o
diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c
new file mode 100644 (file)
index 0000000..0e53d4f
--- /dev/null
@@ -0,0 +1,767 @@
+/*
+ * Driver for Microchip MRF24J40 802.15.4 Wireless-PAN Networking controller
+ *
+ * Copyright (C) 2012 Alan Ott <alan@signal11.us>
+ *                    Signal 11 Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/spi/spi.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <net/wpan-phy.h>
+#include <net/mac802154.h>
+
+/* MRF24J40 Short Address Registers */
+#define REG_RXMCR    0x00  /* Receive MAC control */
+#define REG_PANIDL   0x01  /* PAN ID (low) */
+#define REG_PANIDH   0x02  /* PAN ID (high) */
+#define REG_SADRL    0x03  /* Short address (low) */
+#define REG_SADRH    0x04  /* Short address (high) */
+#define REG_EADR0    0x05  /* Long address (low) (high is EADR7) */
+#define REG_TXMCR    0x11  /* Transmit MAC control */
+#define REG_PACON0   0x16  /* Power Amplifier Control */
+#define REG_PACON1   0x17  /* Power Amplifier Control */
+#define REG_PACON2   0x18  /* Power Amplifier Control */
+#define REG_TXNCON   0x1B  /* Transmit Normal FIFO Control */
+#define REG_TXSTAT   0x24  /* TX MAC Status Register */
+#define REG_SOFTRST  0x2A  /* Soft Reset */
+#define REG_TXSTBL   0x2E  /* TX Stabilization */
+#define REG_INTSTAT  0x31  /* Interrupt Status */
+#define REG_INTCON   0x32  /* Interrupt Control */
+#define REG_RFCTL    0x36  /* RF Control Mode Register */
+#define REG_BBREG1   0x39  /* Baseband Registers */
+#define REG_BBREG2   0x3A  /* */
+#define REG_BBREG6   0x3E  /* */
+#define REG_CCAEDTH  0x3F  /* Energy Detection Threshold */
+
+/* MRF24J40 Long Address Registers */
+#define REG_RFCON0     0x200  /* RF Control Registers */
+#define REG_RFCON1     0x201
+#define REG_RFCON2     0x202
+#define REG_RFCON3     0x203
+#define REG_RFCON5     0x205
+#define REG_RFCON6     0x206
+#define REG_RFCON7     0x207
+#define REG_RFCON8     0x208
+#define REG_RSSI       0x210
+#define REG_SLPCON0    0x211  /* Sleep Clock Control Registers */
+#define REG_SLPCON1    0x220
+#define REG_WAKETIMEL  0x222  /* Wake-up Time Match Value Low */
+#define REG_WAKETIMEH  0x223  /* Wake-up Time Match Value High */
+#define REG_RX_FIFO    0x300  /* Receive FIFO */
+
+/* Device configuration: Only channels 11-26 on page 0 are supported. */
+#define MRF24J40_CHAN_MIN 11
+#define MRF24J40_CHAN_MAX 26
+#define CHANNEL_MASK (((u32)1 << (MRF24J40_CHAN_MAX + 1)) \
+                     - ((u32)1 << MRF24J40_CHAN_MIN))
+
+#define TX_FIFO_SIZE 128 /* From datasheet */
+#define RX_FIFO_SIZE 144 /* From datasheet */
+#define SET_CHANNEL_DELAY_US 192 /* From datasheet */
+
+/* Device Private Data */
+struct mrf24j40 {
+       struct spi_device *spi;
+       struct ieee802154_dev *dev;
+
+       struct mutex buffer_mutex; /* only used to protect buf */
+       struct completion tx_complete;
+       struct work_struct irqwork;
+       u8 *buf; /* 3 bytes. Used for SPI single-register transfers. */
+};
+
+/* Read/Write SPI Commands for Short and Long Address registers. */
+#define MRF24J40_READSHORT(reg) ((reg) << 1)
+#define MRF24J40_WRITESHORT(reg) ((reg) << 1 | 1)
+#define MRF24J40_READLONG(reg) (1 << 15 | (reg) << 5)
+#define MRF24J40_WRITELONG(reg) (1 << 15 | (reg) << 5 | 1 << 4)
+
+/* Maximum speed to run the device at. TODO: Get the real max value from
+ * someone at Microchip since it isn't in the datasheet. */
+#define MAX_SPI_SPEED_HZ 1000000
+
+#define printdev(X) (&X->spi->dev)
+
+static int write_short_reg(struct mrf24j40 *devrec, u8 reg, u8 value)
+{
+       int ret;
+       struct spi_message msg;
+       struct spi_transfer xfer = {
+               .len = 2,
+               .tx_buf = devrec->buf,
+               .rx_buf = devrec->buf,
+       };
+
+       spi_message_init(&msg);
+       spi_message_add_tail(&xfer, &msg);
+
+       mutex_lock(&devrec->buffer_mutex);
+       devrec->buf[0] = MRF24J40_WRITESHORT(reg);
+       devrec->buf[1] = value;
+
+       ret = spi_sync(devrec->spi, &msg);
+       if (ret)
+               dev_err(printdev(devrec),
+                       "SPI write Failed for short register 0x%hhx\n", reg);
+
+       mutex_unlock(&devrec->buffer_mutex);
+       return ret;
+}
+
+static int read_short_reg(struct mrf24j40 *devrec, u8 reg, u8 *val)
+{
+       int ret = -1;
+       struct spi_message msg;
+       struct spi_transfer xfer = {
+               .len = 2,
+               .tx_buf = devrec->buf,
+               .rx_buf = devrec->buf,
+       };
+
+       spi_message_init(&msg);
+       spi_message_add_tail(&xfer, &msg);
+
+       mutex_lock(&devrec->buffer_mutex);
+       devrec->buf[0] = MRF24J40_READSHORT(reg);
+       devrec->buf[1] = 0;
+
+       ret = spi_sync(devrec->spi, &msg);
+       if (ret)
+               dev_err(printdev(devrec),
+                       "SPI read Failed for short register 0x%hhx\n", reg);
+       else
+               *val = devrec->buf[1];
+
+       mutex_unlock(&devrec->buffer_mutex);
+       return ret;
+}
+
+static int read_long_reg(struct mrf24j40 *devrec, u16 reg, u8 *value)
+{
+       int ret;
+       u16 cmd;
+       struct spi_message msg;
+       struct spi_transfer xfer = {
+               .len = 3,
+               .tx_buf = devrec->buf,
+               .rx_buf = devrec->buf,
+       };
+
+       spi_message_init(&msg);
+       spi_message_add_tail(&xfer, &msg);
+
+       cmd = MRF24J40_READLONG(reg);
+       mutex_lock(&devrec->buffer_mutex);
+       devrec->buf[0] = cmd >> 8 & 0xff;
+       devrec->buf[1] = cmd & 0xff;
+       devrec->buf[2] = 0;
+
+       ret = spi_sync(devrec->spi, &msg);
+       if (ret)
+               dev_err(printdev(devrec),
+                       "SPI read Failed for long register 0x%hx\n", reg);
+       else
+               *value = devrec->buf[2];
+
+       mutex_unlock(&devrec->buffer_mutex);
+       return ret;
+}
+
+static int write_long_reg(struct mrf24j40 *devrec, u16 reg, u8 val)
+{
+       int ret;
+       u16 cmd;
+       struct spi_message msg;
+       struct spi_transfer xfer = {
+               .len = 3,
+               .tx_buf = devrec->buf,
+               .rx_buf = devrec->buf,
+       };
+
+       spi_message_init(&msg);
+       spi_message_add_tail(&xfer, &msg);
+
+       cmd = MRF24J40_WRITELONG(reg);
+       mutex_lock(&devrec->buffer_mutex);
+       devrec->buf[0] = cmd >> 8 & 0xff;
+       devrec->buf[1] = cmd & 0xff;
+       devrec->buf[2] = val;
+
+       ret = spi_sync(devrec->spi, &msg);
+       if (ret)
+               dev_err(printdev(devrec),
+                       "SPI write Failed for long register 0x%hx\n", reg);
+
+       mutex_unlock(&devrec->buffer_mutex);
+       return ret;
+}
+
+/* This function relies on an undocumented write method. Once a write command
+   and address is set, as many bytes of data as desired can be clocked into
+   the device. The datasheet only shows setting one byte at a time. */
+static int write_tx_buf(struct mrf24j40 *devrec, u16 reg,
+                       const u8 *data, size_t length)
+{
+       int ret;
+       u16 cmd;
+       u8 lengths[2];
+       struct spi_message msg;
+       struct spi_transfer addr_xfer = {
+               .len = 2,
+               .tx_buf = devrec->buf,
+       };
+       struct spi_transfer lengths_xfer = {
+               .len = 2,
+               .tx_buf = &lengths, /* TODO: Is DMA really required for SPI? */
+       };
+       struct spi_transfer data_xfer = {
+               .len = length,
+               .tx_buf = data,
+       };
+
+       /* Range check the length. 2 bytes are used for the length fields.*/
+       if (length > TX_FIFO_SIZE-2) {
+               dev_err(printdev(devrec), "write_tx_buf() was passed too large a buffer. Performing short write.\n");
+               length = TX_FIFO_SIZE-2;
+       }
+
+       spi_message_init(&msg);
+       spi_message_add_tail(&addr_xfer, &msg);
+       spi_message_add_tail(&lengths_xfer, &msg);
+       spi_message_add_tail(&data_xfer, &msg);
+
+       cmd = MRF24J40_WRITELONG(reg);
+       mutex_lock(&devrec->buffer_mutex);
+       devrec->buf[0] = cmd >> 8 & 0xff;
+       devrec->buf[1] = cmd & 0xff;
+       lengths[0] = 0x0; /* Header Length. Set to 0 for now. TODO */
+       lengths[1] = length; /* Total length */
+
+       ret = spi_sync(devrec->spi, &msg);
+       if (ret)
+               dev_err(printdev(devrec), "SPI write Failed for TX buf\n");
+
+       mutex_unlock(&devrec->buffer_mutex);
+       return ret;
+}
+
+static int mrf24j40_read_rx_buf(struct mrf24j40 *devrec,
+                               u8 *data, u8 *len, u8 *lqi)
+{
+       u8 rx_len;
+       u8 addr[2];
+       u8 lqi_rssi[2];
+       u16 cmd;
+       int ret;
+       struct spi_message msg;
+       struct spi_transfer addr_xfer = {
+               .len = 2,
+               .tx_buf = &addr,
+       };
+       struct spi_transfer data_xfer = {
+               .len = 0x0, /* set below */
+               .rx_buf = data,
+       };
+       struct spi_transfer status_xfer = {
+               .len = 2,
+               .rx_buf = &lqi_rssi,
+       };
+
+       /* Get the length of the data in the RX FIFO. The length in this
+        * register exclues the 1-byte length field at the beginning. */
+       ret = read_long_reg(devrec, REG_RX_FIFO, &rx_len);
+       if (ret)
+               goto out;
+
+       /* Range check the RX FIFO length, accounting for the one-byte
+        * length field at the begining. */
+       if (rx_len > RX_FIFO_SIZE-1) {
+               dev_err(printdev(devrec), "Invalid length read from device. Performing short read.\n");
+               rx_len = RX_FIFO_SIZE-1;
+       }
+
+       if (rx_len > *len) {
+               /* Passed in buffer wasn't big enough. Should never happen. */
+               dev_err(printdev(devrec), "Buffer not big enough. Performing short read\n");
+               rx_len = *len;
+       }
+
+       /* Set up the commands to read the data. */
+       cmd = MRF24J40_READLONG(REG_RX_FIFO+1);
+       addr[0] = cmd >> 8 & 0xff;
+       addr[1] = cmd & 0xff;
+       data_xfer.len = rx_len;
+
+       spi_message_init(&msg);
+       spi_message_add_tail(&addr_xfer, &msg);
+       spi_message_add_tail(&data_xfer, &msg);
+       spi_message_add_tail(&status_xfer, &msg);
+
+       ret = spi_sync(devrec->spi, &msg);
+       if (ret) {
+               dev_err(printdev(devrec), "SPI RX Buffer Read Failed.\n");
+               goto out;
+       }
+
+       *lqi = lqi_rssi[0];
+       *len = rx_len;
+
+#ifdef DEBUG
+       print_hex_dump(KERN_DEBUG, "mrf24j40 rx: ",
+               DUMP_PREFIX_OFFSET, 16, 1, data, *len, 0);
+       printk(KERN_DEBUG "mrf24j40 rx: lqi: %02hhx rssi: %02hhx\n",
+               lqi_rssi[0], lqi_rssi[1]);
+#endif
+
+out:
+       return ret;
+}
+
+static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb)
+{
+       struct mrf24j40 *devrec = dev->priv;
+       u8 val;
+       int ret = 0;
+
+       dev_dbg(printdev(devrec), "tx packet of %d bytes\n", skb->len);
+
+       ret = write_tx_buf(devrec, 0x000, skb->data, skb->len);
+       if (ret)
+               goto err;
+
+       /* Set TXNTRIG bit of TXNCON to send packet */
+       ret = read_short_reg(devrec, REG_TXNCON, &val);
+       if (ret)
+               goto err;
+       val |= 0x1;
+       val &= ~0x4;
+       write_short_reg(devrec, REG_TXNCON, val);
+
+       INIT_COMPLETION(devrec->tx_complete);
+
+       /* Wait for the device to send the TX complete interrupt. */
+       ret = wait_for_completion_interruptible_timeout(
+                                               &devrec->tx_complete,
+                                               5 * HZ);
+       if (ret == -ERESTARTSYS)
+               goto err;
+       if (ret == 0) {
+               ret = -ETIMEDOUT;
+               goto err;
+       }
+
+       /* Check for send error from the device. */
+       ret = read_short_reg(devrec, REG_TXSTAT, &val);
+       if (ret)
+               goto err;
+       if (val & 0x1) {
+               dev_err(printdev(devrec), "Error Sending. Retry count exceeded\n");
+               ret = -ECOMM; /* TODO: Better error code ? */
+       } else
+               dev_dbg(printdev(devrec), "Packet Sent\n");
+
+err:
+
+       return ret;
+}
+
+static int mrf24j40_ed(struct ieee802154_dev *dev, u8 *level)
+{
+       /* TODO: */
+       printk(KERN_WARNING "mrf24j40: ed not implemented\n");
+       *level = 0;
+       return 0;
+}
+
+static int mrf24j40_start(struct ieee802154_dev *dev)
+{
+       struct mrf24j40 *devrec = dev->priv;
+       u8 val;
+       int ret;
+
+       dev_dbg(printdev(devrec), "start\n");
+
+       ret = read_short_reg(devrec, REG_INTCON, &val);
+       if (ret)
+               return ret;
+       val &= ~(0x1|0x8); /* Clear TXNIE and RXIE. Enable interrupts */
+       write_short_reg(devrec, REG_INTCON, val);
+
+       return 0;
+}
+
+static void mrf24j40_stop(struct ieee802154_dev *dev)
+{
+       struct mrf24j40 *devrec = dev->priv;
+       u8 val;
+       int ret;
+       dev_dbg(printdev(devrec), "stop\n");
+
+       ret = read_short_reg(devrec, REG_INTCON, &val);
+       if (ret)
+               return;
+       val |= 0x1|0x8; /* Set TXNIE and RXIE. Disable Interrupts */
+       write_short_reg(devrec, REG_INTCON, val);
+
+       return;
+}
+
+static int mrf24j40_set_channel(struct ieee802154_dev *dev,
+                               int page, int channel)
+{
+       struct mrf24j40 *devrec = dev->priv;
+       u8 val;
+       int ret;
+
+       dev_dbg(printdev(devrec), "Set Channel %d\n", channel);
+
+       WARN_ON(page != 0);
+       WARN_ON(channel < MRF24J40_CHAN_MIN);
+       WARN_ON(channel > MRF24J40_CHAN_MAX);
+
+       /* Set Channel TODO */
+       val = (channel-11) << 4 | 0x03;
+       write_long_reg(devrec, REG_RFCON0, val);
+
+       /* RF Reset */
+       ret = read_short_reg(devrec, REG_RFCTL, &val);
+       if (ret)
+               return ret;
+       val |= 0x04;
+       write_short_reg(devrec, REG_RFCTL, val);
+       val &= ~0x04;
+       write_short_reg(devrec, REG_RFCTL, val);
+
+       udelay(SET_CHANNEL_DELAY_US); /* per datasheet */
+
+       return 0;
+}
+
+static int mrf24j40_filter(struct ieee802154_dev *dev,
+                          struct ieee802154_hw_addr_filt *filt,
+                          unsigned long changed)
+{
+       struct mrf24j40 *devrec = dev->priv;
+
+       dev_dbg(printdev(devrec), "filter\n");
+
+       if (changed & IEEE802515_AFILT_SADDR_CHANGED) {
+               /* Short Addr */
+               u8 addrh, addrl;
+               addrh = filt->short_addr >> 8 & 0xff;
+               addrl = filt->short_addr & 0xff;
+
+               write_short_reg(devrec, REG_SADRH, addrh);
+               write_short_reg(devrec, REG_SADRL, addrl);
+               dev_dbg(printdev(devrec),
+                       "Set short addr to %04hx\n", filt->short_addr);
+       }
+
+       if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) {
+               /* Device Address */
+               int i;
+               for (i = 0; i < 8; i++)
+                       write_short_reg(devrec, REG_EADR0+i,
+                                       filt->ieee_addr[i]);
+
+#ifdef DEBUG
+               printk(KERN_DEBUG "Set long addr to: ");
+               for (i = 0; i < 8; i++)
+                       printk("%02hhx ", filt->ieee_addr[i]);
+               printk(KERN_DEBUG "\n");
+#endif
+       }
+
+       if (changed & IEEE802515_AFILT_PANID_CHANGED) {
+               /* PAN ID */
+               u8 panidl, panidh;
+               panidh = filt->pan_id >> 8 & 0xff;
+               panidl = filt->pan_id & 0xff;
+               write_short_reg(devrec, REG_PANIDH, panidh);
+               write_short_reg(devrec, REG_PANIDL, panidl);
+
+               dev_dbg(printdev(devrec), "Set PANID to %04hx\n", filt->pan_id);
+       }
+
+       if (changed & IEEE802515_AFILT_PANC_CHANGED) {
+               /* Pan Coordinator */
+               u8 val;
+               int ret;
+
+               ret = read_short_reg(devrec, REG_RXMCR, &val);
+               if (ret)
+                       return ret;
+               if (filt->pan_coord)
+                       val |= 0x8;
+               else
+                       val &= ~0x8;
+               write_short_reg(devrec, REG_RXMCR, val);
+
+               /* REG_SLOTTED is maintained as default (unslotted/CSMA-CA).
+                * REG_ORDER is maintained as default (no beacon/superframe).
+                */
+
+               dev_dbg(printdev(devrec), "Set Pan Coord to %s\n",
+                                       filt->pan_coord ? "on" : "off");
+       }
+
+       return 0;
+}
+
+static int mrf24j40_handle_rx(struct mrf24j40 *devrec)
+{
+       u8 len = RX_FIFO_SIZE;
+       u8 lqi = 0;
+       u8 val;
+       int ret = 0;
+       struct sk_buff *skb;
+
+       /* Turn off reception of packets off the air. This prevents the
+        * device from overwriting the buffer while we're reading it. */
+       ret = read_short_reg(devrec, REG_BBREG1, &val);
+       if (ret)
+               goto out;
+       val |= 4; /* SET RXDECINV */
+       write_short_reg(devrec, REG_BBREG1, val);
+
+       skb = alloc_skb(len, GFP_KERNEL);
+       if (!skb) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = mrf24j40_read_rx_buf(devrec, skb_put(skb, len), &len, &lqi);
+       if (ret < 0) {
+               dev_err(printdev(devrec), "Failure reading RX FIFO\n");
+               kfree_skb(skb);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* Cut off the checksum */
+       skb_trim(skb, len-2);
+
+       /* TODO: Other drivers call ieee20154_rx_irqsafe() here (eg: cc2040,
+        * also from a workqueue).  I think irqsafe is not necessary here.
+        * Can someone confirm? */
+       ieee802154_rx_irqsafe(devrec->dev, skb, lqi);
+
+       dev_dbg(printdev(devrec), "RX Handled\n");
+
+out:
+       /* Turn back on reception of packets off the air. */
+       ret = read_short_reg(devrec, REG_BBREG1, &val);
+       if (ret)
+               return ret;
+       val &= ~0x4; /* Clear RXDECINV */
+       write_short_reg(devrec, REG_BBREG1, val);
+
+       return ret;
+}
+
+static struct ieee802154_ops mrf24j40_ops = {
+       .owner = THIS_MODULE,
+       .xmit = mrf24j40_tx,
+       .ed = mrf24j40_ed,
+       .start = mrf24j40_start,
+       .stop = mrf24j40_stop,
+       .set_channel = mrf24j40_set_channel,
+       .set_hw_addr_filt = mrf24j40_filter,
+};
+
+static irqreturn_t mrf24j40_isr(int irq, void *data)
+{
+       struct mrf24j40 *devrec = data;
+
+       disable_irq_nosync(irq);
+
+       schedule_work(&devrec->irqwork);
+
+       return IRQ_HANDLED;
+}
+
+static void mrf24j40_isrwork(struct work_struct *work)
+{
+       struct mrf24j40 *devrec = container_of(work, struct mrf24j40, irqwork);
+       u8 intstat;
+       int ret;
+
+       /* Read the interrupt status */
+       ret = read_short_reg(devrec, REG_INTSTAT, &intstat);
+       if (ret)
+               goto out;
+
+       /* Check for TX complete */
+       if (intstat & 0x1)
+               complete(&devrec->tx_complete);
+
+       /* Check for Rx */
+       if (intstat & 0x8)
+               mrf24j40_handle_rx(devrec);
+
+out:
+       enable_irq(devrec->spi->irq);
+}
+
+static int __devinit mrf24j40_probe(struct spi_device *spi)
+{
+       int ret = -ENOMEM;
+       u8 val;
+       struct mrf24j40 *devrec;
+
+       printk(KERN_INFO "mrf24j40: probe(). IRQ: %d\n", spi->irq);
+
+       devrec = kzalloc(sizeof(struct mrf24j40), GFP_KERNEL);
+       if (!devrec)
+               goto err_devrec;
+       devrec->buf = kzalloc(3, GFP_KERNEL);
+       if (!devrec->buf)
+               goto err_buf;
+
+       spi->mode = SPI_MODE_0; /* TODO: Is this appropriate for right here? */
+       if (spi->max_speed_hz > MAX_SPI_SPEED_HZ)
+               spi->max_speed_hz = MAX_SPI_SPEED_HZ;
+
+       mutex_init(&devrec->buffer_mutex);
+       init_completion(&devrec->tx_complete);
+       INIT_WORK(&devrec->irqwork, mrf24j40_isrwork);
+       devrec->spi = spi;
+       dev_set_drvdata(&spi->dev, devrec);
+
+       /* Register with the 802154 subsystem */
+
+       devrec->dev = ieee802154_alloc_device(0, &mrf24j40_ops);
+       if (!devrec->dev)
+               goto err_alloc_dev;
+
+       devrec->dev->priv = devrec;
+       devrec->dev->parent = &devrec->spi->dev;
+       devrec->dev->phy->channels_supported[0] = CHANNEL_MASK;
+       devrec->dev->flags = IEEE802154_HW_OMIT_CKSUM|IEEE802154_HW_AACK;
+
+       dev_dbg(printdev(devrec), "registered mrf24j40\n");
+       ret = ieee802154_register_device(devrec->dev);
+       if (ret)
+               goto err_register_device;
+
+       /* Initialize the device.
+               From datasheet section 3.2: Initialization. */
+       write_short_reg(devrec, REG_SOFTRST, 0x07);
+       write_short_reg(devrec, REG_PACON2, 0x98);
+       write_short_reg(devrec, REG_TXSTBL, 0x95);
+       write_long_reg(devrec, REG_RFCON0, 0x03);
+       write_long_reg(devrec, REG_RFCON1, 0x01);
+       write_long_reg(devrec, REG_RFCON2, 0x80);
+       write_long_reg(devrec, REG_RFCON6, 0x90);
+       write_long_reg(devrec, REG_RFCON7, 0x80);
+       write_long_reg(devrec, REG_RFCON8, 0x10);
+       write_long_reg(devrec, REG_SLPCON1, 0x21);
+       write_short_reg(devrec, REG_BBREG2, 0x80);
+       write_short_reg(devrec, REG_CCAEDTH, 0x60);
+       write_short_reg(devrec, REG_BBREG6, 0x40);
+       write_short_reg(devrec, REG_RFCTL, 0x04);
+       write_short_reg(devrec, REG_RFCTL, 0x0);
+       udelay(192);
+
+       /* Set RX Mode. RXMCR<1:0>: 0x0 normal, 0x1 promisc, 0x2 error */
+       ret = read_short_reg(devrec, REG_RXMCR, &val);
+       if (ret)
+               goto err_read_reg;
+       val &= ~0x3; /* Clear RX mode (normal) */
+       write_short_reg(devrec, REG_RXMCR, val);
+
+       ret = request_irq(spi->irq,
+                         mrf24j40_isr,
+                         IRQF_TRIGGER_FALLING,
+                         dev_name(&spi->dev),
+                         devrec);
+
+       if (ret) {
+               dev_err(printdev(devrec), "Unable to get IRQ");
+               goto err_irq;
+       }
+
+       return 0;
+
+err_irq:
+err_read_reg:
+       ieee802154_unregister_device(devrec->dev);
+err_register_device:
+       ieee802154_free_device(devrec->dev);
+err_alloc_dev:
+       kfree(devrec->buf);
+err_buf:
+       kfree(devrec);
+err_devrec:
+       return ret;
+}
+
+static int __devexit mrf24j40_remove(struct spi_device *spi)
+{
+       struct mrf24j40 *devrec = dev_get_drvdata(&spi->dev);
+
+       dev_dbg(printdev(devrec), "remove\n");
+
+       free_irq(spi->irq, devrec);
+       flush_work_sync(&devrec->irqwork); /* TODO: Is this the right call? */
+       ieee802154_unregister_device(devrec->dev);
+       ieee802154_free_device(devrec->dev);
+       /* TODO: Will ieee802154_free_device() wait until ->xmit() is
+        * complete? */
+
+       /* Clean up the SPI stuff. */
+       dev_set_drvdata(&spi->dev, NULL);
+       kfree(devrec->buf);
+       kfree(devrec);
+       return 0;
+}
+
+static const struct spi_device_id mrf24j40_ids[] = {
+       { "mrf24j40", 0 },
+       { "mrf24j40ma", 0 },
+       { },
+};
+MODULE_DEVICE_TABLE(spi, mrf24j40_ids);
+
+static struct spi_driver mrf24j40_driver = {
+       .driver = {
+               .name = "mrf24j40",
+               .bus = &spi_bus_type,
+               .owner = THIS_MODULE,
+       },
+       .id_table = mrf24j40_ids,
+       .probe = mrf24j40_probe,
+       .remove = __devexit_p(mrf24j40_remove),
+};
+
+static int __init mrf24j40_init(void)
+{
+       return spi_register_driver(&mrf24j40_driver);
+}
+
+static void __exit mrf24j40_exit(void)
+{
+       spi_unregister_driver(&mrf24j40_driver);
+}
+
+module_init(mrf24j40_init);
+module_exit(mrf24j40_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alan Ott");
+MODULE_DESCRIPTION("MRF24J40 SPI 802.15.4 Controller Driver");
index 098239a98b196fbf9427301b460cc34735a17ef2..9061ba622ac4c44223eb170e4bd0c5c34ae0d79e 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/device.h>
+#include <linux/of_address.h>
 #include <linux/of_mdio.h>
 #include <linux/module.h>
 #include <linux/init.h>
index b4f67b55ef79c0173f3c788270565587e2c20f71..266af7b38ebcd92ba67dbb38f2172ac70acc6076 100644 (file)
@@ -1886,7 +1886,7 @@ static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
        if (!msg)
                return -ENOMEM;
 
-       hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
+       hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
                          &team_nl_family, 0, TEAM_CMD_NOOP);
        if (IS_ERR(hdr)) {
                err = PTR_ERR(hdr);
@@ -1895,7 +1895,7 @@ static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
 
        genlmsg_end(msg, hdr);
 
-       return genlmsg_unicast(genl_info_net(info), msg, info->snd_pid);
+       return genlmsg_unicast(genl_info_net(info), msg, info->snd_portid);
 
 err_msg_put:
        nlmsg_free(msg);
@@ -1952,7 +1952,7 @@ static int team_nl_send_generic(struct genl_info *info, struct team *team,
        if (err < 0)
                goto err_fill;
 
-       err = genlmsg_unicast(genl_info_net(info), skb, info->snd_pid);
+       err = genlmsg_unicast(genl_info_net(info), skb, info->snd_portid);
        return err;
 
 err_fill:
@@ -1961,11 +1961,11 @@ err_fill:
 }
 
 typedef int team_nl_send_func_t(struct sk_buff *skb,
-                               struct team *team, u32 pid);
+                               struct team *team, u32 portid);
 
-static int team_nl_send_unicast(struct sk_buff *skb, struct team *team, u32 pid)
+static int team_nl_send_unicast(struct sk_buff *skb, struct team *team, u32 portid)
 {
-       return genlmsg_unicast(dev_net(team->dev), skb, pid);
+       return genlmsg_unicast(dev_net(team->dev), skb, portid);
 }
 
 static int team_nl_fill_one_option_get(struct sk_buff *skb, struct team *team,
@@ -2050,13 +2050,13 @@ nest_cancel:
 }
 
 static int __send_and_alloc_skb(struct sk_buff **pskb,
-                               struct team *team, u32 pid,
+                               struct team *team, u32 portid,
                                team_nl_send_func_t *send_func)
 {
        int err;
 
        if (*pskb) {
-               err = send_func(*pskb, team, pid);
+               err = send_func(*pskb, team, portid);
                if (err)
                        return err;
        }
@@ -2066,7 +2066,7 @@ static int __send_and_alloc_skb(struct sk_buff **pskb,
        return 0;
 }
 
-static int team_nl_send_options_get(struct team *team, u32 pid, u32 seq,
+static int team_nl_send_options_get(struct team *team, u32 portid, u32 seq,
                                    int flags, team_nl_send_func_t *send_func,
                                    struct list_head *sel_opt_inst_list)
 {
@@ -2083,11 +2083,11 @@ static int team_nl_send_options_get(struct team *team, u32 pid, u32 seq,
                                    struct team_option_inst, tmp_list);
 
 start_again:
-       err = __send_and_alloc_skb(&skb, team, pid, send_func);
+       err = __send_and_alloc_skb(&skb, team, portid, send_func);
        if (err)
                return err;
 
-       hdr = genlmsg_put(skb, pid, seq, &team_nl_family, flags | NLM_F_MULTI,
+       hdr = genlmsg_put(skb, portid, seq, &team_nl_family, flags | NLM_F_MULTI,
                          TEAM_CMD_OPTIONS_GET);
        if (IS_ERR(hdr))
                return PTR_ERR(hdr);
@@ -2120,15 +2120,15 @@ start_again:
                goto start_again;
 
 send_done:
-       nlh = nlmsg_put(skb, pid, seq, NLMSG_DONE, 0, flags | NLM_F_MULTI);
+       nlh = nlmsg_put(skb, portid, seq, NLMSG_DONE, 0, flags | NLM_F_MULTI);
        if (!nlh) {
-               err = __send_and_alloc_skb(&skb, team, pid, send_func);
+               err = __send_and_alloc_skb(&skb, team, portid, send_func);
                if (err)
                        goto errout;
                goto send_done;
        }
 
-       return send_func(skb, team, pid);
+       return send_func(skb, team, portid);
 
 nla_put_failure:
        err = -EMSGSIZE;
@@ -2151,7 +2151,7 @@ static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info)
 
        list_for_each_entry(opt_inst, &team->option_inst_list, list)
                list_add_tail(&opt_inst->tmp_list, &sel_opt_inst_list);
-       err = team_nl_send_options_get(team, info->snd_pid, info->snd_seq,
+       err = team_nl_send_options_get(team, info->snd_portid, info->snd_seq,
                                       NLM_F_ACK, team_nl_send_unicast,
                                       &sel_opt_inst_list);
 
@@ -2305,7 +2305,7 @@ team_put:
 }
 
 static int team_nl_fill_port_list_get(struct sk_buff *skb,
-                                     u32 pid, u32 seq, int flags,
+                                     u32 portid, u32 seq, int flags,
                                      struct team *team,
                                      bool fillall)
 {
@@ -2313,7 +2313,7 @@ static int team_nl_fill_port_list_get(struct sk_buff *skb,
        void *hdr;
        struct team_port *port;
 
-       hdr = genlmsg_put(skb, pid, seq, &team_nl_family, flags,
+       hdr = genlmsg_put(skb, portid, seq, &team_nl_family, flags,
                          TEAM_CMD_PORT_LIST_GET);
        if (IS_ERR(hdr))
                return PTR_ERR(hdr);
@@ -2362,7 +2362,7 @@ static int team_nl_fill_port_list_get_all(struct sk_buff *skb,
                                          struct genl_info *info, int flags,
                                          struct team *team)
 {
-       return team_nl_fill_port_list_get(skb, info->snd_pid,
+       return team_nl_fill_port_list_get(skb, info->snd_portid,
                                          info->snd_seq, NLM_F_ACK,
                                          team, true);
 }
@@ -2415,7 +2415,7 @@ static struct genl_multicast_group team_change_event_mcgrp = {
 };
 
 static int team_nl_send_multicast(struct sk_buff *skb,
-                                 struct team *team, u32 pid)
+                                 struct team *team, u32 portid)
 {
        return genlmsg_multicast_netns(dev_net(team->dev), skb, 0,
                                       team_change_event_mcgrp.id, GFP_KERNEL);
index 328397c66730cae37a9c1cdc02cdb7dde523e2b3..84923334ca5b9f763d3ed4cf19146f8f522116e9 100644 (file)
@@ -108,7 +108,7 @@ static int qmi_wwan_register_subdriver(struct usbnet *dev)
        atomic_set(&info->pmcount, 0);
 
        /* register subdriver */
-       subdriver = usb_cdc_wdm_register(info->control, &dev->status->desc, 512, &qmi_wwan_cdc_wdm_manage_power);
+       subdriver = usb_cdc_wdm_register(info->control, &dev->status->desc, 4096, &qmi_wwan_cdc_wdm_manage_power);
        if (IS_ERR(subdriver)) {
                dev_err(&info->control->dev, "subdriver registration failed\n");
                rv = PTR_ERR(subdriver);
@@ -139,10 +139,18 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
 
        BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state)));
 
-       /* require a single interrupt status endpoint for subdriver */
+       /* control and data is shared? */
+       if (intf->cur_altsetting->desc.bNumEndpoints == 3) {
+               info->control = intf;
+               info->data = intf;
+               goto shared;
+       }
+
+       /* else require a single interrupt status endpoint on control intf */
        if (intf->cur_altsetting->desc.bNumEndpoints != 1)
                goto err;
 
+       /* and a number of CDC descriptors */
        while (len > 3) {
                struct usb_descriptor_header *h = (void *)buf;
 
@@ -231,8 +239,9 @@ next_desc:
        if (status < 0)
                goto err;
 
+shared:
        status = qmi_wwan_register_subdriver(dev);
-       if (status < 0) {
+       if (status < 0 && info->control != info->data) {
                usb_set_intfdata(info->data, NULL);
                usb_driver_release_interface(driver, info->data);
        }
@@ -241,20 +250,6 @@ err:
        return status;
 }
 
-/* Some devices combine the "control" and "data" functions into a
- * single interface with all three endpoints: interrupt + bulk in and
- * out
- */
-static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf)
-{
-       struct qmi_wwan_state *info = (void *)&dev->data;
-
-       /*  control and data is shared */
-       info->control = intf;
-       info->data = intf;
-       return qmi_wwan_register_subdriver(dev);
-}
-
 static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf)
 {
        struct qmi_wwan_state *info = (void *)&dev->data;
@@ -330,20 +325,12 @@ static const struct driver_info   qmi_wwan_info = {
        .manage_power   = qmi_wwan_manage_power,
 };
 
-static const struct driver_info        qmi_wwan_shared = {
-       .description    = "WWAN/QMI device",
-       .flags          = FLAG_WWAN,
-       .bind           = qmi_wwan_bind_shared,
-       .unbind         = qmi_wwan_unbind,
-       .manage_power   = qmi_wwan_manage_power,
-};
-
 #define HUAWEI_VENDOR_ID       0x12D1
 
 /* map QMI/wwan function by a fixed interface number */
 #define QMI_FIXED_INTF(vend, prod, num) \
        USB_DEVICE_INTERFACE_NUMBER(vend, prod, num), \
-       .driver_info = (unsigned long)&qmi_wwan_shared
+       .driver_info = (unsigned long)&qmi_wwan_info
 
 /* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */
 #define QMI_GOBI1K_DEVICE(vend, prod) \
@@ -367,15 +354,15 @@ static const struct usb_device_id products[] = {
        /* 2. Combined interface devices matching on class+protocol */
        {       /* Huawei E392, E398 and possibly others in "Windows mode" */
                USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17),
-               .driver_info        = (unsigned long)&qmi_wwan_shared,
+               .driver_info        = (unsigned long)&qmi_wwan_info,
        },
        {       /* Pantech UML290 */
                USB_DEVICE_AND_INTERFACE_INFO(0x106c, 0x3718, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff),
-               .driver_info        = (unsigned long)&qmi_wwan_shared,
+               .driver_info        = (unsigned long)&qmi_wwan_info,
        },
        {       /* Pantech UML290 - newer firmware */
                USB_DEVICE_AND_INTERFACE_INFO(0x106c, 0x3718, USB_CLASS_VENDOR_SPEC, 0xf1, 0xff),
-               .driver_info        = (unsigned long)&qmi_wwan_shared,
+               .driver_info        = (unsigned long)&qmi_wwan_info,
        },
 
        /* 3. Combined interface devices matching on interface number */
@@ -457,7 +444,7 @@ static int qmi_wwan_probe(struct usb_interface *intf, const struct usb_device_id
         */
        if (!id->driver_info) {
                dev_dbg(&intf->dev, "setting defaults for dynamic device id\n");
-               id->driver_info = (unsigned long)&qmi_wwan_shared;
+               id->driver_info = (unsigned long)&qmi_wwan_info;
        }
 
        return usbnet_probe(intf, id);
index 7ae70e9489d5cc469314c154400b8d5cb01b5b51..dfbdfe8086506c5298dccbfc27b346142d5121ea 100644 (file)
@@ -838,7 +838,7 @@ static int sierra_net_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
                                netdev_err(dev->net, "HIP/ETH: Invalid pkt\n");
 
                        dev->net->stats.rx_frame_errors++;
-                       /* dev->net->stats.rx_errors incremented by caller */;
+                       /* dev->net->stats.rx_errors incremented by caller */
                        return 0;
                }
 
index 72b0456e41bfe002bb67ac57e5736ecbd5622e0e..9d45b3bb974c2efad968af4827b40ce1b2218c2e 100644 (file)
@@ -38,7 +38,7 @@ MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211");
 MODULE_LICENSE("GPL");
 
-static u32 wmediumd_pid;
+static u32 wmediumd_portid;
 
 static int radios = 2;
 module_param(radios, int, 0444);
@@ -545,7 +545,7 @@ static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data,
 
 static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
                                       struct sk_buff *my_skb,
-                                      int dst_pid)
+                                      int dst_portid)
 {
        struct sk_buff *skb;
        struct mac80211_hwsim_data *data = hw->priv;
@@ -619,7 +619,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
                goto nla_put_failure;
 
        genlmsg_end(skb, msg_head);
-       genlmsg_unicast(&init_net, skb, dst_pid);
+       genlmsg_unicast(&init_net, skb, dst_portid);
 
        /* Enqueue the packet */
        skb_queue_tail(&data->pending, my_skb);
@@ -715,7 +715,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
 {
        bool ack;
        struct ieee80211_tx_info *txi;
-       u32 _pid;
+       u32 _portid;
 
        mac80211_hwsim_monitor_rx(hw, skb);
 
@@ -726,10 +726,10 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
        }
 
        /* wmediumd mode check */
-       _pid = ACCESS_ONCE(wmediumd_pid);
+       _portid = ACCESS_ONCE(wmediumd_portid);
 
-       if (_pid)
-               return mac80211_hwsim_tx_frame_nl(hw, skb, _pid);
+       if (_portid)
+               return mac80211_hwsim_tx_frame_nl(hw, skb, _portid);
 
        /* NO wmediumd detected, perfect medium simulation */
        ack = mac80211_hwsim_tx_frame_no_nl(hw, skb);
@@ -814,7 +814,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
        struct ieee80211_hw *hw = arg;
        struct sk_buff *skb;
        struct ieee80211_tx_info *info;
-       u32 _pid;
+       u32 _portid;
 
        hwsim_check_magic(vif);
 
@@ -831,10 +831,10 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
        mac80211_hwsim_monitor_rx(hw, skb);
 
        /* wmediumd mode check */
-       _pid = ACCESS_ONCE(wmediumd_pid);
+       _portid = ACCESS_ONCE(wmediumd_portid);
 
-       if (_pid)
-               return mac80211_hwsim_tx_frame_nl(hw, skb, _pid);
+       if (_portid)
+               return mac80211_hwsim_tx_frame_nl(hw, skb, _portid);
 
        mac80211_hwsim_tx_frame_no_nl(hw, skb);
        dev_kfree_skb(skb);
@@ -1315,7 +1315,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
        struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
        struct sk_buff *skb;
        struct ieee80211_pspoll *pspoll;
-       u32 _pid;
+       u32 _portid;
 
        if (!vp->assoc)
                return;
@@ -1336,10 +1336,10 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
        memcpy(pspoll->ta, mac, ETH_ALEN);
 
        /* wmediumd mode check */
-       _pid = ACCESS_ONCE(wmediumd_pid);
+       _portid = ACCESS_ONCE(wmediumd_portid);
 
-       if (_pid)
-               return mac80211_hwsim_tx_frame_nl(data->hw, skb, _pid);
+       if (_portid)
+               return mac80211_hwsim_tx_frame_nl(data->hw, skb, _portid);
 
        if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb))
                printk(KERN_DEBUG "%s: PS-poll frame not ack'ed\n", __func__);
@@ -1353,7 +1353,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
        struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
        struct sk_buff *skb;
        struct ieee80211_hdr *hdr;
-       u32 _pid;
+       u32 _portid;
 
        if (!vp->assoc)
                return;
@@ -1375,10 +1375,10 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
        memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
 
        /* wmediumd mode check */
-       _pid = ACCESS_ONCE(wmediumd_pid);
+       _portid = ACCESS_ONCE(wmediumd_portid);
 
-       if (_pid)
-               return mac80211_hwsim_tx_frame_nl(data->hw, skb, _pid);
+       if (_portid)
+               return mac80211_hwsim_tx_frame_nl(data->hw, skb, _portid);
 
        if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb))
                printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__);
@@ -1632,10 +1632,10 @@ static int hwsim_register_received_nl(struct sk_buff *skb_2,
        if (info == NULL)
                goto out;
 
-       wmediumd_pid = info->snd_pid;
+       wmediumd_portid = info->snd_portid;
 
        printk(KERN_DEBUG "mac80211_hwsim: received a REGISTER, "
-              "switching to wmediumd mode with pid %d\n", info->snd_pid);
+              "switching to wmediumd mode with pid %d\n", info->snd_portid);
 
        return 0;
 out:
@@ -1672,10 +1672,10 @@ static int mac80211_hwsim_netlink_notify(struct notifier_block *nb,
        if (state != NETLINK_URELEASE)
                return NOTIFY_DONE;
 
-       if (notify->pid == wmediumd_pid) {
+       if (notify->portid == wmediumd_portid) {
                printk(KERN_INFO "mac80211_hwsim: wmediumd released netlink"
                       " socket, switching to perfect channel medium\n");
-               wmediumd_pid = 0;
+               wmediumd_portid = 0;
        }
        return NOTIFY_DONE;
 
index 8818dd681c194a445ea937c6f1e4b0dd70efff5f..3252bc9625eed78083c9dd66910c7e42c0053be2 100644 (file)
@@ -501,7 +501,7 @@ scsi_netlink_init(void)
        }
 
        scsi_nl_sock = netlink_kernel_create(&init_net, NETLINK_SCSITRANSPORT,
-                                            THIS_MODULE, &cfg);
+                                            &cfg);
        if (!scsi_nl_sock) {
                printk(KERN_ERR "%s: register of receive handler failed\n",
                                __func__);
index fa1dfaa83e32986061586c4fcb2f6f8e9e23eaf9..31969f2e13ceff07e2304dd0cca84b27c655fa22 100644 (file)
@@ -2119,7 +2119,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
        switch (nlh->nlmsg_type) {
        case ISCSI_UEVENT_CREATE_SESSION:
                err = iscsi_if_create_session(priv, ep, ev,
-                                             NETLINK_CB(skb).pid,
+                                             NETLINK_CB(skb).portid,
                                              ev->u.c_session.initial_cmdsn,
                                              ev->u.c_session.cmds_max,
                                              ev->u.c_session.queue_depth);
@@ -2132,7 +2132,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
                }
 
                err = iscsi_if_create_session(priv, ep, ev,
-                                       NETLINK_CB(skb).pid,
+                                       NETLINK_CB(skb).portid,
                                        ev->u.c_bound_session.initial_cmdsn,
                                        ev->u.c_bound_session.cmds_max,
                                        ev->u.c_bound_session.queue_depth);
@@ -2969,8 +2969,7 @@ static __init int iscsi_transport_init(void)
        if (err)
                goto unregister_conn_class;
 
-       nls = netlink_kernel_create(&init_net, NETLINK_ISCSI,
-                                   THIS_MODULE, &cfg);
+       nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, &cfg);
        if (!nls) {
                err = -ENOBUFS;
                goto unregister_session_class;
index 3abb31df8f28289a2cdad7a5c41c1ab3063123e2..20d0aec52e72fded49622158d11926a7edc6af13 100644 (file)
@@ -95,7 +95,7 @@ struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type,
        init_MUTEX(&netlink_mutex);
 #endif
 
-       sock = netlink_kernel_create(&init_net, unit, THIS_MODULE, &cfg);
+       sock = netlink_kernel_create(&init_net, unit, &cfg);
 
        if (sock)
                rcv_cb = cb;
@@ -135,7 +135,7 @@ int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len)
        }
        memcpy(nlmsg_data(nlh), msg, len);
 
-       NETLINK_CB(skb).pid = 0;
+       NETLINK_CB(skb).portid = 0;
        NETLINK_CB(skb).dst_group = 0;
 
        ret = netlink_broadcast(sock, skb, 0, group+1, GFP_ATOMIC);
index ef17e0169da187ed209164a7881befcf00eec97f..60a327863b1122e246b79bf91ecdf23136eccac9 100644 (file)
@@ -14,7 +14,7 @@
 #include "dlm_internal.h"
 
 static uint32_t dlm_nl_seqnum;
-static uint32_t listener_nlpid;
+static uint32_t listener_nlportid;
 
 static struct genl_family family = {
        .id             = GENL_ID_GENERATE,
@@ -64,13 +64,13 @@ static int send_data(struct sk_buff *skb)
                return rv;
        }
 
-       return genlmsg_unicast(&init_net, skb, listener_nlpid);
+       return genlmsg_unicast(&init_net, skb, listener_nlportid);
 }
 
 static int user_cmd(struct sk_buff *skb, struct genl_info *info)
 {
-       listener_nlpid = info->snd_pid;
-       printk("user_cmd nlpid %u\n", listener_nlpid);
+       listener_nlportid = info->snd_portid;
+       printk("user_cmd nlpid %u\n", listener_nlportid);
        return 0;
 }
 
index 1f2c1c787f1785361a57892a0d62d44e905e7b67..90da0af283521e67111715815fb7b4c75c921168 100644 (file)
@@ -363,6 +363,7 @@ header-y += sysctl.h
 header-y += sysinfo.h
 header-y += taskstats.h
 header-y += tcp.h
+header-y += tcp_metrics.h
 header-y += telephony.h
 header-y += termios.h
 header-y += time.h
index d426336d92d9e4bb34f5f049bc7f4f05d49303bb..b006ba0a9f4269e79d8bfae11415e8b3c8785f69 100644 (file)
@@ -150,6 +150,17 @@ static inline void eth_broadcast_addr(u8 *addr)
        memset(addr, 0xff, ETH_ALEN);
 }
 
+/**
+ * eth_zero_addr - Assign zero address
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Assign the zero address to the given address array.
+ */
+static inline void eth_zero_addr(u8 *addr)
+{
+       memset(addr, 0x00, ETH_ALEN);
+}
+
 /**
  * eth_hw_addr_random - Generate software assigned random Ethernet and
  * set device flag
index 82b01357af8b0672c330c648f3b01f5aa65134d2..3cf5fd561d8649ce9647bce45a0e40dc28124a91 100644 (file)
@@ -74,6 +74,8 @@ struct sock_fprog {   /* Required for SO_ATTACH_FILTER. */
 #define         BPF_LSH         0x60
 #define         BPF_RSH         0x70
 #define         BPF_NEG         0x80
+#define                BPF_MOD         0x90
+
 #define         BPF_JA          0x00
 #define         BPF_JEQ         0x10
 #define         BPF_JGT         0x20
@@ -196,6 +198,8 @@ enum {
        BPF_S_ALU_MUL_K,
        BPF_S_ALU_MUL_X,
        BPF_S_ALU_DIV_X,
+       BPF_S_ALU_MOD_K,
+       BPF_S_ALU_MOD_X,
        BPF_S_ALU_AND_K,
        BPF_S_ALU_AND_X,
        BPF_S_ALU_OR_K,
index ccac82e61604873c7b3b2ec26251e1ae45b46c1e..ae3153c0db0a750b00888ed012d1e8be13a9fa96 100644 (file)
@@ -1322,6 +1322,8 @@ struct net_device {
        /* phy device may attach itself for hardware timestamping */
        struct phy_device *phydev;
 
+       struct lock_class_key *qdisc_tx_busylock;
+
        /* group the device belongs to */
        int group;
 
index c9fdde2bc73f422951da472cf1636da900a93ad2..73ade5fbc8563eab3c584fa84f963dff4aceafab 100644 (file)
@@ -153,6 +153,8 @@ struct nlattr {
 
 #include <linux/capability.h>
 #include <linux/skbuff.h>
+#include <linux/module.h>
+#include <net/scm.h>
 
 struct net;
 
@@ -162,8 +164,8 @@ static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb)
 }
 
 struct netlink_skb_parms {
-       struct ucred            creds;          /* Skb credentials      */
-       __u32                   pid;
+       struct scm_creds        creds;          /* Skb credentials      */
+       __u32                   portid;
        __u32                   dst_group;
        struct sock             *ssk;
 };
@@ -175,17 +177,27 @@ struct netlink_skb_parms {
 extern void netlink_table_grab(void);
 extern void netlink_table_ungrab(void);
 
+#define NL_CFG_F_NONROOT_RECV  (1 << 0)
+#define NL_CFG_F_NONROOT_SEND  (1 << 1)
+
 /* optional Netlink kernel configuration parameters */
 struct netlink_kernel_cfg {
        unsigned int    groups;
        void            (*input)(struct sk_buff *skb);
        struct mutex    *cb_mutex;
        void            (*bind)(int group);
+       unsigned int    flags;
 };
 
-extern struct sock *netlink_kernel_create(struct net *net, int unit,
-                                         struct module *module,
-                                         struct netlink_kernel_cfg *cfg);
+extern struct sock *__netlink_kernel_create(struct net *net, int unit,
+                                           struct module *module,
+                                           struct netlink_kernel_cfg *cfg);
+static inline struct sock *
+netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg)
+{
+       return __netlink_kernel_create(net, unit, THIS_MODULE, cfg);
+}
+
 extern void netlink_kernel_release(struct sock *sk);
 extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups);
 extern int netlink_change_ngroups(struct sock *sk, unsigned int groups);
@@ -193,14 +205,14 @@ extern void __netlink_clear_multicast_users(struct sock *sk, unsigned int group)
 extern void netlink_clear_multicast_users(struct sock *sk, unsigned int group);
 extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err);
 extern int netlink_has_listeners(struct sock *sk, unsigned int group);
-extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock);
-extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid,
+extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 portid, int nonblock);
+extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 portid,
                             __u32 group, gfp_t allocation);
 extern int netlink_broadcast_filtered(struct sock *ssk, struct sk_buff *skb,
-       __u32 pid, __u32 group, gfp_t allocation,
+       __u32 portid, __u32 group, gfp_t allocation,
        int (*filter)(struct sock *dsk, struct sk_buff *skb, void *data),
        void *filter_data);
-extern int netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code);
+extern int netlink_set_err(struct sock *ssk, __u32 portid, __u32 group, int code);
 extern int netlink_register_notifier(struct notifier_block *nb);
 extern int netlink_unregister_notifier(struct notifier_block *nb);
 
@@ -241,12 +253,12 @@ struct netlink_callback {
 
 struct netlink_notify {
        struct net *net;
-       int pid;
+       int portid;
        int protocol;
 };
 
 struct nlmsghdr *
-__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags);
+__nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, int type, int len, int flags);
 
 struct netlink_dump_control {
        int (*dump)(struct sk_buff *skb, struct netlink_callback *);
@@ -259,11 +271,6 @@ extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
                              const struct nlmsghdr *nlh,
                              struct netlink_dump_control *control);
 
-
-#define NL_NONROOT_RECV 0x1
-#define NL_NONROOT_SEND 0x2
-extern void netlink_set_nonroot(int protocol, unsigned flag);
-
 #endif /* __KERNEL__ */
 
 #endif /* __LINUX_NETLINK_H */
diff --git a/include/linux/tcp_metrics.h b/include/linux/tcp_metrics.h
new file mode 100644 (file)
index 0000000..cb5157b
--- /dev/null
@@ -0,0 +1,54 @@
+/* tcp_metrics.h - TCP Metrics Interface */
+
+#ifndef _LINUX_TCP_METRICS_H
+#define _LINUX_TCP_METRICS_H
+
+#include <linux/types.h>
+
+/* NETLINK_GENERIC related info
+ */
+#define TCP_METRICS_GENL_NAME          "tcp_metrics"
+#define TCP_METRICS_GENL_VERSION       0x1
+
+enum tcp_metric_index {
+       TCP_METRIC_RTT,
+       TCP_METRIC_RTTVAR,
+       TCP_METRIC_SSTHRESH,
+       TCP_METRIC_CWND,
+       TCP_METRIC_REORDERING,
+
+       /* Always last.  */
+       __TCP_METRIC_MAX,
+};
+
+#define TCP_METRIC_MAX (__TCP_METRIC_MAX - 1)
+
+enum {
+       TCP_METRICS_ATTR_UNSPEC,
+       TCP_METRICS_ATTR_ADDR_IPV4,             /* u32 */
+       TCP_METRICS_ATTR_ADDR_IPV6,             /* binary */
+       TCP_METRICS_ATTR_AGE,                   /* msecs */
+       TCP_METRICS_ATTR_TW_TSVAL,              /* u32, raw, rcv tsval */
+       TCP_METRICS_ATTR_TW_TS_STAMP,           /* s32, sec age */
+       TCP_METRICS_ATTR_VALS,                  /* nested +1, u32 */
+       TCP_METRICS_ATTR_FOPEN_MSS,             /* u16 */
+       TCP_METRICS_ATTR_FOPEN_SYN_DROPS,       /* u16, count of drops */
+       TCP_METRICS_ATTR_FOPEN_SYN_DROP_TS,     /* msecs age */
+       TCP_METRICS_ATTR_FOPEN_COOKIE,          /* binary */
+
+       __TCP_METRICS_ATTR_MAX,
+};
+
+#define TCP_METRICS_ATTR_MAX   (__TCP_METRICS_ATTR_MAX - 1)
+
+enum {
+       TCP_METRICS_CMD_UNSPEC,
+       TCP_METRICS_CMD_GET,
+       TCP_METRICS_CMD_DEL,
+
+       __TCP_METRICS_CMD_MAX,
+};
+
+#define TCP_METRICS_CMD_MAX    (__TCP_METRICS_CMD_MAX - 1)
+
+#endif /* _LINUX_TCP_METRICS_H */
index ba2e6160fad1d74cc755ef15a1056f15089c0ff4..7b3b0568d289d7718a83a40df625d6ce0b3138d5 100644 (file)
@@ -2458,7 +2458,7 @@ struct wireless_dev {
 
        int beacon_interval;
 
-       u32 ap_unexpected_nlpid;
+       u32 ap_unexpected_nlportid;
 
 #ifdef CONFIG_CFG80211_WEXT
        /* wext data */
index 48905cd3884c8d687ba3f109e31f5268ee42feb1..bdfbe68c1c3b271bf20b2ef23d5d0325bda2f906 100644 (file)
@@ -65,7 +65,7 @@ struct genl_family {
 /**
  * struct genl_info - receiving information
  * @snd_seq: sending sequence number
- * @snd_pid: netlink pid of sender
+ * @snd_portid: netlink portid of sender
  * @nlhdr: netlink message header
  * @genlhdr: generic netlink message header
  * @userhdr: user specific header
@@ -75,7 +75,7 @@ struct genl_family {
  */
 struct genl_info {
        u32                     snd_seq;
-       u32                     snd_pid;
+       u32                     snd_portid;
        struct nlmsghdr *       nlhdr;
        struct genlmsghdr *     genlhdr;
        void *                  userhdr;
@@ -130,10 +130,10 @@ extern int genl_register_mc_group(struct genl_family *family,
                                  struct genl_multicast_group *grp);
 extern void genl_unregister_mc_group(struct genl_family *family,
                                     struct genl_multicast_group *grp);
-extern void genl_notify(struct sk_buff *skb, struct net *net, u32 pid,
+extern void genl_notify(struct sk_buff *skb, struct net *net, u32 portid,
                        u32 group, struct nlmsghdr *nlh, gfp_t flags);
 
-void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
+void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
                                struct genl_family *family, int flags, u8 cmd);
 
 /**
@@ -183,7 +183,7 @@ static inline void *genlmsg_put_reply(struct sk_buff *skb,
                                      struct genl_family *family,
                                      int flags, u8 cmd)
 {
-       return genlmsg_put(skb, info->snd_pid, info->snd_seq, family,
+       return genlmsg_put(skb, info->snd_portid, info->snd_seq, family,
                           flags, cmd);
 }
 
@@ -212,49 +212,49 @@ static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
  * genlmsg_multicast_netns - multicast a netlink message to a specific netns
  * @net: the net namespace
  * @skb: netlink message as socket buffer
- * @pid: own netlink pid to avoid sending to yourself
+ * @portid: own netlink portid to avoid sending to yourself
  * @group: multicast group id
  * @flags: allocation flags
  */
 static inline int genlmsg_multicast_netns(struct net *net, struct sk_buff *skb,
-                                         u32 pid, unsigned int group, gfp_t flags)
+                                         u32 portid, unsigned int group, gfp_t flags)
 {
-       return nlmsg_multicast(net->genl_sock, skb, pid, group, flags);
+       return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
 }
 
 /**
  * genlmsg_multicast - multicast a netlink message to the default netns
  * @skb: netlink message as socket buffer
- * @pid: own netlink pid to avoid sending to yourself
+ * @portid: own netlink portid to avoid sending to yourself
  * @group: multicast group id
  * @flags: allocation flags
  */
-static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid,
+static inline int genlmsg_multicast(struct sk_buff *skb, u32 portid,
                                    unsigned int group, gfp_t flags)
 {
-       return genlmsg_multicast_netns(&init_net, skb, pid, group, flags);
+       return genlmsg_multicast_netns(&init_net, skb, portid, group, flags);
 }
 
 /**
  * genlmsg_multicast_allns - multicast a netlink message to all net namespaces
  * @skb: netlink message as socket buffer
- * @pid: own netlink pid to avoid sending to yourself
+ * @portid: own netlink portid to avoid sending to yourself
  * @group: multicast group id
  * @flags: allocation flags
  *
  * This function must hold the RTNL or rcu_read_lock().
  */
-int genlmsg_multicast_allns(struct sk_buff *skb, u32 pid,
+int genlmsg_multicast_allns(struct sk_buff *skb, u32 portid,
                            unsigned int group, gfp_t flags);
 
 /**
  * genlmsg_unicast - unicast a netlink message
  * @skb: netlink message as socket buffer
- * @pid: netlink pid of the destination socket
+ * @portid: netlink portid of the destination socket
  */
-static inline int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 pid)
+static inline int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 portid)
 {
-       return nlmsg_unicast(net->genl_sock, skb, pid);
+       return nlmsg_unicast(net->genl_sock, skb, portid);
 }
 
 /**
@@ -264,7 +264,7 @@ static inline int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 pid)
  */
 static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info)
 {
-       return genlmsg_unicast(genl_info_net(info), skb, info->snd_pid);
+       return genlmsg_unicast(genl_info_net(info), skb, info->snd_portid);
 }
 
 /**
index 0fedbd8d747a049db1810fdc325b032d62782b1b..cd64cf35a49f2f9acb5a3c7b81f4e08f7b459454 100644 (file)
@@ -37,6 +37,7 @@ struct fib6_config {
        int             fc_ifindex;
        u32             fc_flags;
        u32             fc_protocol;
+       u32             fc_type;        /* only 8 bits are used */
 
        struct in6_addr fc_dst;
        struct in6_addr fc_src;
index 4a045cda9c60c75a96b956b051dfbf5a6d6581b7..5654d292efd4f0883f6051610f6144552f20cb61 100644 (file)
@@ -17,7 +17,7 @@ struct nf_conntrack_ecache {
        unsigned long missed;   /* missed events */
        u16 ctmask;             /* bitmask of ct events to be delivered */
        u16 expmask;            /* bitmask of expect events to be delivered */
-       u32 pid;                /* netlink pid of destroyer */
+       u32 portid;             /* netlink portid of destroyer */
        struct timer_list timeout;
 };
 
@@ -60,7 +60,7 @@ nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp)
 /* This structure is passed to event handler */
 struct nf_ct_event {
        struct nf_conn *ct;
-       u32 pid;
+       u32 portid;
        int report;
 };
 
@@ -92,7 +92,7 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
 static inline int
 nf_conntrack_eventmask_report(unsigned int eventmask,
                              struct nf_conn *ct,
-                             u32 pid,
+                             u32 portid,
                              int report)
 {
        int ret = 0;
@@ -112,11 +112,11 @@ nf_conntrack_eventmask_report(unsigned int eventmask,
        if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
                struct nf_ct_event item = {
                        .ct     = ct,
-                       .pid    = e->pid ? e->pid : pid,
+                       .portid = e->portid ? e->portid : portid,
                        .report = report
                };
                /* This is a resent of a destroy event? If so, skip missed */
-               unsigned long missed = e->pid ? 0 : e->missed;
+               unsigned long missed = e->portid ? 0 : e->missed;
 
                if (!((eventmask | missed) & e->ctmask))
                        goto out_unlock;
@@ -126,11 +126,11 @@ nf_conntrack_eventmask_report(unsigned int eventmask,
                        spin_lock_bh(&ct->lock);
                        if (ret < 0) {
                                /* This is a destroy event that has been
-                                * triggered by a process, we store the PID
+                                * triggered by a process, we store the PORTID
                                 * to include it in the retransmission. */
                                if (eventmask & (1 << IPCT_DESTROY) &&
-                                   e->pid == 0 && pid != 0)
-                                       e->pid = pid;
+                                   e->portid == 0 && portid != 0)
+                                       e->portid = portid;
                                else
                                        e->missed |= eventmask;
                        } else
@@ -145,9 +145,9 @@ out_unlock:
 
 static inline int
 nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct,
-                         u32 pid, int report)
+                         u32 portid, int report)
 {
-       return nf_conntrack_eventmask_report(1 << event, ct, pid, report);
+       return nf_conntrack_eventmask_report(1 << event, ct, portid, report);
 }
 
 static inline int
@@ -158,7 +158,7 @@ nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
 
 struct nf_exp_event {
        struct nf_conntrack_expect *exp;
-       u32 pid;
+       u32 portid;
        int report;
 };
 
@@ -172,7 +172,7 @@ extern void nf_ct_expect_unregister_notifier(struct net *net, struct nf_exp_even
 static inline void
 nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
                          struct nf_conntrack_expect *exp,
-                         u32 pid,
+                         u32 portid,
                          int report)
 {
        struct net *net = nf_ct_exp_net(exp);
@@ -191,7 +191,7 @@ nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
        if (e->expmask & (1 << event)) {
                struct nf_exp_event item = {
                        .exp    = exp,
-                       .pid    = pid,
+                       .portid = portid,
                        .report = report
                };
                notify->fcn(1 << event, &item);
@@ -216,20 +216,20 @@ static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
                                            struct nf_conn *ct) {}
 static inline int nf_conntrack_eventmask_report(unsigned int eventmask,
                                                struct nf_conn *ct,
-                                               u32 pid,
+                                               u32 portid,
                                                int report) { return 0; }
 static inline int nf_conntrack_event(enum ip_conntrack_events event,
                                     struct nf_conn *ct) { return 0; }
 static inline int nf_conntrack_event_report(enum ip_conntrack_events event,
                                            struct nf_conn *ct,
-                                           u32 pid,
+                                           u32 portid,
                                            int report) { return 0; }
 static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
 static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
                                      struct nf_conntrack_expect *exp) {}
 static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e,
                                             struct nf_conntrack_expect *exp,
-                                            u32 pid,
+                                            u32 portid,
                                             int report) {}
 
 static inline int nf_conntrack_ecache_init(struct net *net)
index 09175d5d1fbf15e56dbf4ae7406e886f0dce1602..9690b0f6698a1d1b433ea572bdc4efb938f501c5 100644 (file)
@@ -217,19 +217,19 @@ struct nla_policy {
 /**
  * struct nl_info - netlink source information
  * @nlh: Netlink message header of original request
- * @pid: Netlink PID of requesting application
+ * @portid: Netlink PORTID of requesting application
  */
 struct nl_info {
        struct nlmsghdr         *nlh;
        struct net              *nl_net;
-       u32                     pid;
+       u32                     portid;
 };
 
 extern int             netlink_rcv_skb(struct sk_buff *skb,
                                        int (*cb)(struct sk_buff *,
                                                  struct nlmsghdr *));
 extern int             nlmsg_notify(struct sock *sk, struct sk_buff *skb,
-                                    u32 pid, unsigned int group, int report,
+                                    u32 portid, unsigned int group, int report,
                                     gfp_t flags);
 
 extern int             nla_validate(const struct nlattr *head,
@@ -444,7 +444,7 @@ static inline int nlmsg_report(const struct nlmsghdr *nlh)
 /**
  * nlmsg_put - Add a new netlink message to an skb
  * @skb: socket buffer to store message in
- * @pid: netlink process id
+ * @portid: netlink process id
  * @seq: sequence number of message
  * @type: message type
  * @payload: length of message payload
@@ -453,13 +453,13 @@ static inline int nlmsg_report(const struct nlmsghdr *nlh)
  * Returns NULL if the tailroom of the skb is insufficient to store
  * the message header and payload.
  */
-static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
+static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
                                         int type, int payload, int flags)
 {
        if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload)))
                return NULL;
 
-       return __nlmsg_put(skb, pid, seq, type, payload, flags);
+       return __nlmsg_put(skb, portid, seq, type, payload, flags);
 }
 
 /**
@@ -478,7 +478,7 @@ static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb,
                                                int type, int payload,
                                                int flags)
 {
-       return nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
+       return nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
                         type, payload, flags);
 }
 
@@ -563,18 +563,18 @@ static inline void nlmsg_free(struct sk_buff *skb)
  * nlmsg_multicast - multicast a netlink message
  * @sk: netlink socket to spread messages to
  * @skb: netlink message as socket buffer
- * @pid: own netlink pid to avoid sending to yourself
+ * @portid: own netlink portid to avoid sending to yourself
  * @group: multicast group id
  * @flags: allocation flags
  */
 static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
-                                 u32 pid, unsigned int group, gfp_t flags)
+                                 u32 portid, unsigned int group, gfp_t flags)
 {
        int err;
 
        NETLINK_CB(skb).dst_group = group;
 
-       err = netlink_broadcast(sk, skb, pid, group, flags);
+       err = netlink_broadcast(sk, skb, portid, group, flags);
        if (err > 0)
                err = 0;
 
@@ -585,13 +585,13 @@ static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
  * nlmsg_unicast - unicast a netlink message
  * @sk: netlink socket to spread message to
  * @skb: netlink message as socket buffer
- * @pid: netlink pid of the destination socket
+ * @portid: netlink portid of the destination socket
  */
-static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 pid)
+static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 portid)
 {
        int err;
 
-       err = netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
+       err = netlink_unicast(sk, skb, portid, MSG_DONTWAIT);
        if (err > 0)
                err = 0;
 
index 6431f5e3902217cba706b36f269844242f907856..6735909f826d565b51c4e29a62add003561ed026 100644 (file)
@@ -89,7 +89,7 @@ struct nfc_target {
 };
 
 struct nfc_genl_data {
-       u32 poll_req_pid;
+       u32 poll_req_portid;
        struct mutex genl_data_mutex;
 };
 
index 776a27f1ab78ef5a385ef8b8d2f21b9e0101e115..da22243d27600cd66b5fb70da61f5cadc05d5468 100644 (file)
@@ -108,7 +108,7 @@ extern struct ip_rt_acct __percpu *ip_rt_acct;
 
 struct in_device;
 extern int             ip_rt_init(void);
-extern void            rt_cache_flush(struct net *net, int how);
+extern void            rt_cache_flush(struct net *net);
 extern void            rt_flush_dev(struct net_device *dev);
 extern struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp);
 extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
index 7dc0854f0b3891992696002b7f75edf7a01233ab..456695f5cbc4004be9b10b3a676aab080dab2634 100644 (file)
  */
 #define SCM_MAX_FD     253
 
+struct scm_creds {
+       u32     pid;
+       kuid_t  uid;
+       kgid_t  gid;
+};
+
 struct scm_fp_list {
        short                   count;
        short                   max;
@@ -22,7 +28,7 @@ struct scm_cookie {
        struct pid              *pid;           /* Skb credentials */
        const struct cred       *cred;
        struct scm_fp_list      *fp;            /* Passed files         */
-       struct ucred            creds;          /* Skb credentials      */
+       struct scm_creds        creds;          /* Skb credentials      */
 #ifdef CONFIG_SECURITY_NETWORK
        u32                     secid;          /* Passed security ID   */
 #endif
@@ -49,7 +55,9 @@ static __inline__ void scm_set_cred(struct scm_cookie *scm,
 {
        scm->pid  = get_pid(pid);
        scm->cred = cred ? get_cred(cred) : NULL;
-       cred_to_ucred(pid, cred, &scm->creds);
+       scm->creds.pid = pid_vnr(pid);
+       scm->creds.uid = cred ? cred->euid : INVALID_UID;
+       scm->creds.gid = cred ? cred->egid : INVALID_GID;
 }
 
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
@@ -112,8 +120,15 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
                return;
        }
 
-       if (test_bit(SOCK_PASSCRED, &sock->flags))
-               put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
+       if (test_bit(SOCK_PASSCRED, &sock->flags)) {
+               struct user_namespace *current_ns = current_user_ns();
+               struct ucred ucreds = {
+                       .pid = scm->creds.pid,
+                       .uid = from_kuid_munged(current_ns, scm->creds.uid),
+                       .gid = from_kgid_munged(current_ns, scm->creds.gid),
+               };
+               put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
+       }
 
        scm_destroy_cred(scm);
 
index 36ad56ba648b3cbd849e7a13928332abf3bdc8cd..ee8613f01860eef134c2bd2c91349b9410ba62b3 100644 (file)
@@ -263,7 +263,7 @@ struct km_event {
        } data;
 
        u32     seq;
-       u32     pid;
+       u32     portid;
        u32     event;
        struct net *net;
 };
@@ -310,7 +310,7 @@ extern void km_state_notify(struct xfrm_state *x, const struct km_event *c);
 
 struct xfrm_tmpl;
 extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
-extern void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
+extern void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
 extern int __xfrm_state_delete(struct xfrm_state *x);
 
 struct xfrm_state_afinfo {
@@ -1554,7 +1554,7 @@ extern int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 #endif
 
 extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
-extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid);
+extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid);
 extern int km_report(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
 
 extern void xfrm_input_init(void);
index ea3b7b6191c7af3347dce055a88af200c55d1f5d..e0cf64a0ae2d00aa13482857100e44381f4c1063 100644 (file)
@@ -87,11 +87,11 @@ static int  audit_failure = AUDIT_FAIL_PRINTK;
 
 /*
  * If audit records are to be written to the netlink socket, audit_pid
- * contains the pid of the auditd process and audit_nlk_pid contains
- * the pid to use to send netlink messages to that process.
+ * contains the pid of the auditd process and audit_nlk_portid contains
+ * the portid to use to send netlink messages to that process.
  */
 int            audit_pid;
-static int     audit_nlk_pid;
+static int     audit_nlk_portid;
 
 /* If audit_rate_limit is non-zero, limit the rate of sending audit records
  * to that number per second.  This prevents DoS attacks, but results in
@@ -401,7 +401,7 @@ static void kauditd_send_skb(struct sk_buff *skb)
        int err;
        /* take a reference in case we can't send it and we want to hold it */
        skb_get(skb);
-       err = netlink_unicast(audit_sock, skb, audit_nlk_pid, 0);
+       err = netlink_unicast(audit_sock, skb, audit_nlk_portid, 0);
        if (err < 0) {
                BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */
                printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid);
@@ -692,7 +692,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                status_set.backlog_limit = audit_backlog_limit;
                status_set.lost          = atomic_read(&audit_lost);
                status_set.backlog       = skb_queue_len(&audit_skb_queue);
-               audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_GET, 0, 0,
+               audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0,
                                 &status_set, sizeof(status_set));
                break;
        case AUDIT_SET:
@@ -720,7 +720,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                                                        sessionid, sid, 1);
 
                        audit_pid = new_pid;
-                       audit_nlk_pid = NETLINK_CB(skb).pid;
+                       audit_nlk_portid = NETLINK_CB(skb).portid;
                }
                if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) {
                        err = audit_set_rate_limit(status_get->rate_limit,
@@ -782,7 +782,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                }
                /* fallthrough */
        case AUDIT_LIST:
-               err = audit_receive_filter(msg_type, NETLINK_CB(skb).pid,
+               err = audit_receive_filter(msg_type, NETLINK_CB(skb).portid,
                                           uid, seq, data, nlmsg_len(nlh),
                                           loginuid, sessionid, sid);
                break;
@@ -801,7 +801,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                }
                /* fallthrough */
        case AUDIT_LIST_RULES:
-               err = audit_receive_filter(msg_type, NETLINK_CB(skb).pid,
+               err = audit_receive_filter(msg_type, NETLINK_CB(skb).portid,
                                           uid, seq, data, nlmsg_len(nlh),
                                           loginuid, sessionid, sid);
                break;
@@ -872,7 +872,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                        memcpy(sig_data->ctx, ctx, len);
                        security_release_secctx(ctx, len);
                }
-               audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO,
+               audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_SIGNAL_INFO,
                                0, 0, sig_data, sizeof(*sig_data) + len);
                kfree(sig_data);
                break;
@@ -891,7 +891,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                rcu_read_unlock();
 
                if (!err)
-                       audit_send_reply(NETLINK_CB(skb).pid, seq,
+                       audit_send_reply(NETLINK_CB(skb).portid, seq,
                                         AUDIT_TTY_GET, 0, 0, &s, sizeof(s));
                break;
        }
@@ -971,8 +971,7 @@ static int __init audit_init(void)
 
        printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
               audit_default ? "enabled" : "disabled");
-       audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT,
-                                          THIS_MODULE, &cfg);
+       audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, &cfg);
        if (!audit_sock)
                audit_panic("cannot initialize netlink socket");
        else
index d0a32796550fcdf81e40d18cda31a3b353d332d5..123793cd06f931477ae61cb7666a466b616bdfb5 100644 (file)
@@ -467,7 +467,7 @@ static int cmd_attr_register_cpumask(struct genl_info *info)
        rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], mask);
        if (rc < 0)
                goto out;
-       rc = add_del_listener(info->snd_pid, mask, REGISTER);
+       rc = add_del_listener(info->snd_portid, mask, REGISTER);
 out:
        free_cpumask_var(mask);
        return rc;
@@ -483,7 +483,7 @@ static int cmd_attr_deregister_cpumask(struct genl_info *info)
        rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], mask);
        if (rc < 0)
                goto out;
-       rc = add_del_listener(info->snd_pid, mask, DEREGISTER);
+       rc = add_del_listener(info->snd_portid, mask, DEREGISTER);
 out:
        free_cpumask_var(mask);
        return rc;
index 0401d2916d9fa25515540c0483dd486adaddc858..52e5abbc41dbc0724e9b6664e7674b6bd680ca53 100644 (file)
@@ -375,14 +375,14 @@ static int uevent_net_init(struct net *net)
        struct uevent_sock *ue_sk;
        struct netlink_kernel_cfg cfg = {
                .groups = 1,
+               .flags  = NL_CFG_F_NONROOT_RECV,
        };
 
        ue_sk = kzalloc(sizeof(*ue_sk), GFP_KERNEL);
        if (!ue_sk)
                return -ENOMEM;
 
-       ue_sk->sk = netlink_kernel_create(net, NETLINK_KOBJECT_UEVENT,
-                                         THIS_MODULE, &cfg);
+       ue_sk->sk = netlink_kernel_create(net, NETLINK_KOBJECT_UEVENT, &cfg);
        if (!ue_sk->sk) {
                printk(KERN_ERR
                       "kobject_uevent: unable to create netlink socket!\n");
@@ -422,7 +422,6 @@ static struct pernet_operations uevent_net_ops = {
 
 static int __init kobject_uevent_init(void)
 {
-       netlink_set_nonroot(NETLINK_KOBJECT_UEVENT, NL_NONROOT_RECV);
        return register_pernet_subsys(&uevent_net_ops);
 }
 
index 245831bec09a56dd263cde753050d10208ee0200..30b48f523135be8f00025f32b887b51f0f7000c3 100644 (file)
@@ -52,6 +52,8 @@ source "net/iucv/Kconfig"
 
 config INET
        bool "TCP/IP networking"
+       select CRYPTO
+       select CRYPTO_AES
        ---help---
          These are the protocols used on the Internet and on most local
          Ethernets. It is highly recommended to say Y here (this will enlarge
index 9ce430b4657c2781efa84b136122b1292516f53d..ddf93efc133c6a308687fa5ff6eeefed12efb333 100644 (file)
@@ -467,14 +467,14 @@ static int fdb_to_nud(const struct net_bridge_fdb_entry *fdb)
 
 static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br,
                         const struct net_bridge_fdb_entry *fdb,
-                        u32 pid, u32 seq, int type, unsigned int flags)
+                        u32 portid, u32 seq, int type, unsigned int flags)
 {
        unsigned long now = jiffies;
        struct nda_cacheinfo ci;
        struct nlmsghdr *nlh;
        struct ndmsg *ndm;
 
-       nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags);
+       nlh = nlmsg_put(skb, portid, seq, type, sizeof(*ndm), flags);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -555,7 +555,7 @@ int br_fdb_dump(struct sk_buff *skb,
                                goto skip;
 
                        if (fdb_fill_info(skb, br, f,
-                                         NETLINK_CB(cb->skb).pid,
+                                         NETLINK_CB(cb->skb).portid,
                                          cb->nlh->nlmsg_seq,
                                          RTM_NEWNEIGH,
                                          NLM_F_MULTI) < 0)
index fe41260fbf38b28bb121dcc2235a5d27b83e27b7..093f527276a39c097de23cea8ab7e4016df438cc 100644 (file)
@@ -127,7 +127,7 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
                        goto skip;
 
                if (br_fill_ifinfo(skb, port,
-                                  NETLINK_CB(cb->skb).pid,
+                                  NETLINK_CB(cb->skb).portid,
                                   cb->nlh->nlmsg_seq, RTM_NEWLINK,
                                   NLM_F_MULTI) < 0)
                        break;
index 19063473c71f2efc897e2ee3a51ea023052f15e6..3476ec469740d6829deed8089888353d7934d4a5 100644 (file)
@@ -298,8 +298,7 @@ static int __init ebt_ulog_init(void)
                spin_lock_init(&ulog_buffers[i].lock);
        }
 
-       ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
-                                         THIS_MODULE, &cfg);
+       ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, &cfg);
        if (!ebtulognl)
                ret = -ENOMEM;
        else if ((ret = xt_register_target(&ebt_ulog_tg_reg)) != 0)
index b54d5e695b034b8abbd3c0dc083fc74c5d1cf15e..127879c55fb66f9d3e6698def42013c1561ab58b 100644 (file)
@@ -549,7 +549,7 @@ static int cgw_dump_jobs(struct sk_buff *skb, struct netlink_callback *cb)
                if (idx < s_idx)
                        goto cont;
 
-               if (cgw_put_job(skb, gwj, RTM_NEWROUTE, NETLINK_CB(cb->skb).pid,
+               if (cgw_put_job(skb, gwj, RTM_NEWROUTE, NETLINK_CB(cb->skb).portid,
                    cb->nlh->nlmsg_seq, NLM_F_MULTI) < 0)
                        break;
 cont:
index ab7db83236c96fa2b4746ffc25717f24db671e17..58a4ba27dfe3117d439ada122000e1339a23f48f 100644 (file)
@@ -402,7 +402,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
        if (unresolved)
                ops->unresolved_rules++;
 
-       notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).pid);
+       notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).portid);
        flush_route_cache(ops);
        rules_ops_put(ops);
        return 0;
@@ -500,7 +500,7 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
                }
 
                notify_rule_change(RTM_DELRULE, rule, ops, nlh,
-                                  NETLINK_CB(skb).pid);
+                                  NETLINK_CB(skb).portid);
                if (ops->delete)
                        ops->delete(rule);
                fib_rule_put(rule);
@@ -601,7 +601,7 @@ static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb,
                if (idx < cb->args[1])
                        goto skip;
 
-               if (fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).pid,
+               if (fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).portid,
                                     cb->nlh->nlmsg_seq, RTM_NEWRULE,
                                     NLM_F_MULTI, ops) < 0)
                        break;
index 907efd27ec77bcf5f3f214058dce27fc77e873bd..fbe3a8d12570b9604825043e9f68764af15b0aa0 100644 (file)
@@ -167,6 +167,14 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
                case BPF_S_ALU_DIV_K:
                        A = reciprocal_divide(A, K);
                        continue;
+               case BPF_S_ALU_MOD_X:
+                       if (X == 0)
+                               return 0;
+                       A %= X;
+                       continue;
+               case BPF_S_ALU_MOD_K:
+                       A %= K;
+                       continue;
                case BPF_S_ALU_AND_X:
                        A &= X;
                        continue;
@@ -469,6 +477,8 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
                [BPF_ALU|BPF_MUL|BPF_K]  = BPF_S_ALU_MUL_K,
                [BPF_ALU|BPF_MUL|BPF_X]  = BPF_S_ALU_MUL_X,
                [BPF_ALU|BPF_DIV|BPF_X]  = BPF_S_ALU_DIV_X,
+               [BPF_ALU|BPF_MOD|BPF_K]  = BPF_S_ALU_MOD_K,
+               [BPF_ALU|BPF_MOD|BPF_X]  = BPF_S_ALU_MOD_X,
                [BPF_ALU|BPF_AND|BPF_K]  = BPF_S_ALU_AND_K,
                [BPF_ALU|BPF_AND|BPF_X]  = BPF_S_ALU_AND_X,
                [BPF_ALU|BPF_OR|BPF_K]   = BPF_S_ALU_OR_K,
@@ -531,6 +541,11 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
                                return -EINVAL;
                        ftest->k = reciprocal_value(ftest->k);
                        break;
+               case BPF_S_ALU_MOD_K:
+                       /* check for division by zero */
+                       if (ftest->k == 0)
+                               return -EINVAL;
+                       break;
                case BPF_S_LD_MEM:
                case BPF_S_LDX_MEM:
                case BPF_S_ST:
index 117afaf512689b4de570ddb0c32869a4c5532918..c160adb38e5ad631d6687750a730a3c12af7f84b 100644 (file)
@@ -2102,7 +2102,7 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
                if (tidx < tbl_skip || (family && tbl->family != family))
                        continue;
 
-               if (neightbl_fill_info(skb, tbl, NETLINK_CB(cb->skb).pid,
+               if (neightbl_fill_info(skb, tbl, NETLINK_CB(cb->skb).portid,
                                       cb->nlh->nlmsg_seq, RTM_NEWNEIGHTBL,
                                       NLM_F_MULTI) <= 0)
                        break;
@@ -2115,7 +2115,7 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
                                goto next;
 
                        if (neightbl_fill_param_info(skb, tbl, p,
-                                                    NETLINK_CB(cb->skb).pid,
+                                                    NETLINK_CB(cb->skb).portid,
                                                     cb->nlh->nlmsg_seq,
                                                     RTM_NEWNEIGHTBL,
                                                     NLM_F_MULTI) <= 0)
@@ -2244,7 +2244,7 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
                                continue;
                        if (idx < s_idx)
                                goto next;
-                       if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid,
+                       if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).portid,
                                            cb->nlh->nlmsg_seq,
                                            RTM_NEWNEIGH,
                                            NLM_F_MULTI) <= 0) {
@@ -2281,7 +2281,7 @@ static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
                                continue;
                        if (idx < s_idx)
                                goto next;
-                       if (pneigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid,
+                       if (pneigh_fill_info(skb, n, NETLINK_CB(cb->skb).portid,
                                            cb->nlh->nlmsg_seq,
                                            RTM_NEWNEIGH,
                                            NLM_F_MULTI, tbl) <= 0) {
index 72607174ea5a4af158855f588b767b5c4c86d973..bcf02f608cbfa76ad06da490f2dbf423e728fc17 100644 (file)
@@ -166,9 +166,21 @@ static ssize_t show_duplex(struct device *dev,
 
        if (netif_running(netdev)) {
                struct ethtool_cmd cmd;
-               if (!__ethtool_get_settings(netdev, &cmd))
-                       ret = sprintf(buf, "%s\n",
-                                     cmd.duplex ? "full" : "half");
+               if (!__ethtool_get_settings(netdev, &cmd)) {
+                       const char *duplex;
+                       switch (cmd.duplex) {
+                       case DUPLEX_HALF:
+                               duplex = "half";
+                               break;
+                       case DUPLEX_FULL:
+                               duplex = "full";
+                               break;
+                       default:
+                               duplex = "unknown";
+                               break;
+                       }
+                       ret = sprintf(buf, "%s\n", duplex);
+               }
        }
        rtnl_unlock();
        return ret;
index c64efcff80787ab6d6f3837a38c975e12b068b98..92575370d9f0af3ba18d3bab0a2576c94986c749 100644 (file)
@@ -1081,7 +1081,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
                        if (idx < s_idx)
                                goto cont;
                        if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
-                                            NETLINK_CB(cb->skb).pid,
+                                            NETLINK_CB(cb->skb).portid,
                                             cb->nlh->nlmsg_seq, 0,
                                             NLM_F_MULTI,
                                             ext_filter_mask) <= 0)
@@ -1899,14 +1899,14 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
        if (nskb == NULL)
                return -ENOBUFS;
 
-       err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid,
+       err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).portid,
                               nlh->nlmsg_seq, 0, 0, ext_filter_mask);
        if (err < 0) {
                /* -EMSGSIZE implies BUG in if_nlmsg_size */
                WARN_ON(err == -EMSGSIZE);
                kfree_skb(nskb);
        } else
-               err = rtnl_unicast(nskb, net, NETLINK_CB(skb).pid);
+               err = rtnl_unicast(nskb, net, NETLINK_CB(skb).portid);
 
        return err;
 }
@@ -2180,9 +2180,9 @@ static int nlmsg_populate_fdb(struct sk_buff *skb,
 {
        struct netdev_hw_addr *ha;
        int err;
-       u32 pid, seq;
+       u32 portid, seq;
 
-       pid = NETLINK_CB(cb->skb).pid;
+       portid = NETLINK_CB(cb->skb).portid;
        seq = cb->nlh->nlmsg_seq;
 
        list_for_each_entry(ha, &list->list, list) {
@@ -2190,7 +2190,7 @@ static int nlmsg_populate_fdb(struct sk_buff *skb,
                        goto skip;
 
                err = nlmsg_populate_fdb_fill(skb, dev, ha->addr,
-                                             pid, seq, 0, NTF_SELF);
+                                             portid, seq, 0, NTF_SELF);
                if (err < 0)
                        return err;
 skip:
@@ -2381,9 +2381,10 @@ static int __net_init rtnetlink_net_init(struct net *net)
                .groups         = RTNLGRP_MAX,
                .input          = rtnetlink_rcv,
                .cb_mutex       = &rtnl_mutex,
+               .flags          = NL_CFG_F_NONROOT_RECV,
        };
 
-       sk = netlink_kernel_create(net, NETLINK_ROUTE, THIS_MODULE, &cfg);
+       sk = netlink_kernel_create(net, NETLINK_ROUTE, &cfg);
        if (!sk)
                return -ENOMEM;
        net->rtnl = sk;
@@ -2416,7 +2417,6 @@ void __init rtnetlink_init(void)
        if (register_pernet_subsys(&rtnetlink_net_ops))
                panic("rtnetlink_init: cannot initialize rtnetlink\n");
 
-       netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV);
        register_netdevice_notifier(&rtnetlink_dev_notifier);
 
        rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink,
index 6ab491d6c26f43d84da26e9e0fc90a477ab49cea..9c1c63da3ca8a99ce8ac25e8f1abf9e309075740 100644 (file)
@@ -155,19 +155,21 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)
                        break;
                case SCM_CREDENTIALS:
                {
+                       struct ucred creds;
                        kuid_t uid;
                        kgid_t gid;
                        if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred)))
                                goto error;
-                       memcpy(&p->creds, CMSG_DATA(cmsg), sizeof(struct ucred));
-                       err = scm_check_creds(&p->creds);
+                       memcpy(&creds, CMSG_DATA(cmsg), sizeof(struct ucred));
+                       err = scm_check_creds(&creds);
                        if (err)
                                goto error;
 
-                       if (!p->pid || pid_vnr(p->pid) != p->creds.pid) {
+                       p->creds.pid = creds.pid;
+                       if (!p->pid || pid_vnr(p->pid) != creds.pid) {
                                struct pid *pid;
                                err = -ESRCH;
-                               pid = find_get_pid(p->creds.pid);
+                               pid = find_get_pid(creds.pid);
                                if (!pid)
                                        goto error;
                                put_pid(p->pid);
@@ -175,11 +177,14 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)
                        }
 
                        err = -EINVAL;
-                       uid = make_kuid(current_user_ns(), p->creds.uid);
-                       gid = make_kgid(current_user_ns(), p->creds.gid);
+                       uid = make_kuid(current_user_ns(), creds.uid);
+                       gid = make_kgid(current_user_ns(), creds.gid);
                        if (!uid_valid(uid) || !gid_valid(gid))
                                goto error;
 
+                       p->creds.uid = uid;
+                       p->creds.gid = gid;
+
                        if (!p->cred ||
                            !uid_eq(p->cred->euid, uid) ||
                            !gid_eq(p->cred->egid, gid)) {
index 9d8755e4a7a51e8415818f6c3542ef56c0697c08..602cd637182ebb321af6773d2ccfe9a8945d44c5 100644 (file)
@@ -172,8 +172,7 @@ static int __net_init diag_net_init(struct net *net)
                .input  = sock_diag_rcv,
        };
 
-       net->diag_nlsk = netlink_kernel_create(net, NETLINK_SOCK_DIAG,
-                                              THIS_MODULE, &cfg);
+       net->diag_nlsk = netlink_kernel_create(net, NETLINK_SOCK_DIAG, &cfg);
        return net->diag_nlsk == NULL ? -ENOMEM : 0;
 }
 
index 81f2bb62dea3a7fdd569636fa8649350eb264a35..70989e672304938a39cdf7b7a0dfd87b7497d2a9 100644 (file)
@@ -1319,7 +1319,7 @@ nla_put_failure:
 }
 
 static int dcbnl_notify(struct net_device *dev, int event, int cmd,
-                       u32 seq, u32 pid, int dcbx_ver)
+                       u32 seq, u32 portid, int dcbx_ver)
 {
        struct net *net = dev_net(dev);
        struct sk_buff *skb;
@@ -1330,7 +1330,7 @@ static int dcbnl_notify(struct net_device *dev, int event, int cmd,
        if (!ops)
                return -EOPNOTSUPP;
 
-       skb = dcbnl_newmsg(event, cmd, pid, seq, 0, &nlh);
+       skb = dcbnl_newmsg(event, cmd, portid, seq, 0, &nlh);
        if (!skb)
                return -ENOBUFS;
 
@@ -1353,16 +1353,16 @@ static int dcbnl_notify(struct net_device *dev, int event, int cmd,
 }
 
 int dcbnl_ieee_notify(struct net_device *dev, int event, int cmd,
-                     u32 seq, u32 pid)
+                     u32 seq, u32 portid)
 {
-       return dcbnl_notify(dev, event, cmd, seq, pid, DCB_CAP_DCBX_VER_IEEE);
+       return dcbnl_notify(dev, event, cmd, seq, portid, DCB_CAP_DCBX_VER_IEEE);
 }
 EXPORT_SYMBOL(dcbnl_ieee_notify);
 
 int dcbnl_cee_notify(struct net_device *dev, int event, int cmd,
-                    u32 seq, u32 pid)
+                    u32 seq, u32 portid)
 {
-       return dcbnl_notify(dev, event, cmd, seq, pid, DCB_CAP_DCBX_VER_CEE);
+       return dcbnl_notify(dev, event, cmd, seq, portid, DCB_CAP_DCBX_VER_CEE);
 }
 EXPORT_SYMBOL(dcbnl_cee_notify);
 
@@ -1656,7 +1656,7 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
        struct net_device *netdev;
        struct dcbmsg *dcb = nlmsg_data(nlh);
        struct nlattr *tb[DCB_ATTR_MAX + 1];
-       u32 pid = skb ? NETLINK_CB(skb).pid : 0;
+       u32 portid = skb ? NETLINK_CB(skb).portid : 0;
        int ret = -EINVAL;
        struct sk_buff *reply_skb;
        struct nlmsghdr *reply_nlh = NULL;
@@ -1690,7 +1690,7 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
                goto out;
        }
 
-       reply_skb = dcbnl_newmsg(fn->type, dcb->cmd, pid, nlh->nlmsg_seq,
+       reply_skb = dcbnl_newmsg(fn->type, dcb->cmd, portid, nlh->nlmsg_seq,
                                 nlh->nlmsg_flags, &reply_nlh);
        if (!reply_skb) {
                ret = -ENOBUFS;
@@ -1705,7 +1705,7 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 
        nlmsg_end(reply_skb, reply_nlh);
 
-       ret = rtnl_unicast(reply_skb, &init_net, pid);
+       ret = rtnl_unicast(reply_skb, &init_net, portid);
 out:
        dev_put(netdev);
        return ret;
index f3924ab1e019f5efc22f6278021078889f43ce52..7b7e561412d379380a54678b1505da796184c49c 100644 (file)
@@ -667,12 +667,12 @@ static inline size_t dn_ifaddr_nlmsg_size(void)
 }
 
 static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa,
-                            u32 pid, u32 seq, int event, unsigned int flags)
+                            u32 portid, u32 seq, int event, unsigned int flags)
 {
        struct ifaddrmsg *ifm;
        struct nlmsghdr *nlh;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*ifm), flags);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -753,7 +753,7 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
                        if (dn_idx < skip_naddr)
                                continue;
 
-                       if (dn_nl_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
+                       if (dn_nl_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).portid,
                                              cb->nlh->nlmsg_seq, RTM_NEWADDR,
                                              NLM_F_MULTI) < 0)
                                goto done;
index c855e8d0738f75a08a1d44a35a02ff870132510f..b57419cc41a486b3ab2ddc82643169c97b19d132 100644 (file)
@@ -1543,7 +1543,7 @@ static int dn_route_input(struct sk_buff *skb)
        return dn_route_input_slow(skb);
 }
 
-static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
+static int dn_rt_fill_info(struct sk_buff *skb, u32 portid, u32 seq,
                           int event, int nowait, unsigned int flags)
 {
        struct dn_route *rt = (struct dn_route *)skb_dst(skb);
@@ -1551,7 +1551,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
        struct nlmsghdr *nlh;
        long expires;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*r), flags);
        if (!nlh)
                return -EMSGSIZE;
 
@@ -1685,7 +1685,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
        if (rtm->rtm_flags & RTM_F_NOTIFY)
                rt->rt_flags |= RTCF_NOTIFY;
 
-       err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0, 0);
+       err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq, RTM_NEWROUTE, 0, 0);
 
        if (err == 0)
                goto out_free;
@@ -1694,7 +1694,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
                goto out_free;
        }
 
-       return rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
+       return rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).portid);
 
 out_free:
        kfree_skb(skb);
@@ -1737,7 +1737,7 @@ int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb)
                        if (idx < s_idx)
                                continue;
                        skb_dst_set(skb, dst_clone(&rt->dst));
-                       if (dn_rt_fill_info(skb, NETLINK_CB(cb->skb).pid,
+                       if (dn_rt_fill_info(skb, NETLINK_CB(cb->skb).portid,
                                        cb->nlh->nlmsg_seq, RTM_NEWROUTE,
                                        1, NLM_F_MULTI) <= 0) {
                                skb_dst_drop(skb);
index 16c986ab1228ec7f5cf5821253938705b8b6a808..f968c1b58f47d1892ee392eea366d67f4c687397 100644 (file)
@@ -291,14 +291,14 @@ static inline size_t dn_fib_nlmsg_size(struct dn_fib_info *fi)
        return payload;
 }
 
-static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
+static int dn_fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
                        u32 tb_id, u8 type, u8 scope, void *dst, int dst_len,
                        struct dn_fib_info *fi, unsigned int flags)
 {
        struct rtmsg *rtm;
        struct nlmsghdr *nlh;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*rtm), flags);
        if (!nlh)
                return -EMSGSIZE;
 
@@ -374,14 +374,14 @@ static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id,
                        struct nlmsghdr *nlh, struct netlink_skb_parms *req)
 {
        struct sk_buff *skb;
-       u32 pid = req ? req->pid : 0;
+       u32 portid = req ? req->portid : 0;
        int err = -ENOBUFS;
 
        skb = nlmsg_new(dn_fib_nlmsg_size(DN_FIB_INFO(f)), GFP_KERNEL);
        if (skb == NULL)
                goto errout;
 
-       err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id,
+       err = dn_fib_dump_info(skb, portid, nlh->nlmsg_seq, event, tb_id,
                               f->fn_type, f->fn_scope, &f->fn_key, z,
                               DN_FIB_INFO(f), 0);
        if (err < 0) {
@@ -390,7 +390,7 @@ static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id,
                kfree_skb(skb);
                goto errout;
        }
-       rtnl_notify(skb, &init_net, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
+       rtnl_notify(skb, &init_net, portid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
        return;
 errout:
        if (err < 0)
@@ -411,7 +411,7 @@ static __inline__ int dn_hash_dump_bucket(struct sk_buff *skb,
                        continue;
                if (f->fn_state & DN_S_ZOMBIE)
                        continue;
-               if (dn_fib_dump_info(skb, NETLINK_CB(cb->skb).pid,
+               if (dn_fib_dump_info(skb, NETLINK_CB(cb->skb).portid,
                                cb->nlh->nlmsg_seq,
                                RTM_NEWROUTE,
                                tb->n,
index 11db0ecf342ff2f32901acdb24836055ca0e383c..dfe42012a044142dbc9c0bf6197f539fd1996a8b 100644 (file)
@@ -130,8 +130,7 @@ static int __init dn_rtmsg_init(void)
                .input  = dnrmg_receive_user_skb,
        };
 
-       dnrmg = netlink_kernel_create(&init_net,
-                                     NETLINK_DNRTMSG, THIS_MODULE, &cfg);
+       dnrmg = netlink_kernel_create(&init_net, NETLINK_DNRTMSG, &cfg);
        if (dnrmg == NULL) {
                printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket");
                return -ENOMEM;
index 1e9917124e75ccada73d34e3a19578155db4dec9..96bb08abece29408f0d9d65f453ee7f2c0c55c4e 100644 (file)
@@ -246,7 +246,7 @@ nla_put_failure:
 }
 EXPORT_SYMBOL(ieee802154_nl_start_confirm);
 
-static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
+static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid,
        u32 seq, int flags, struct net_device *dev)
 {
        void *hdr;
@@ -534,7 +534,7 @@ static int ieee802154_list_iface(struct sk_buff *skb,
        if (!msg)
                goto out_dev;
 
-       rc = ieee802154_nl_fill_iface(msg, info->snd_pid, info->snd_seq,
+       rc = ieee802154_nl_fill_iface(msg, info->snd_portid, info->snd_seq,
                        0, dev);
        if (rc < 0)
                goto out_free;
@@ -565,7 +565,7 @@ static int ieee802154_dump_iface(struct sk_buff *skb,
                if (idx < s_idx || (dev->type != ARPHRD_IEEE802154))
                        goto cont;
 
-               if (ieee802154_nl_fill_iface(skb, NETLINK_CB(cb->skb).pid,
+               if (ieee802154_nl_fill_iface(skb, NETLINK_CB(cb->skb).portid,
                        cb->nlh->nlmsg_seq, NLM_F_MULTI, dev) < 0)
                        break;
 cont:
index d54be34cca9442b2cb1624ad167e205bea718832..22b1a7058fd3f841d94ee27655840c1ae325f011 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "ieee802154.h"
 
-static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 pid,
+static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid,
        u32 seq, int flags, struct wpan_phy *phy)
 {
        void *hdr;
@@ -105,7 +105,7 @@ static int ieee802154_list_phy(struct sk_buff *skb,
        if (!msg)
                goto out_dev;
 
-       rc = ieee802154_nl_fill_phy(msg, info->snd_pid, info->snd_seq,
+       rc = ieee802154_nl_fill_phy(msg, info->snd_portid, info->snd_seq,
                        0, phy);
        if (rc < 0)
                goto out_free;
@@ -138,7 +138,7 @@ static int ieee802154_dump_phy_iter(struct wpan_phy *phy, void *_data)
                return 0;
 
        rc = ieee802154_nl_fill_phy(data->skb,
-                       NETLINK_CB(data->cb->skb).pid,
+                       NETLINK_CB(data->cb->skb).portid,
                        data->cb->nlh->nlmsg_seq,
                        NLM_F_MULTI,
                        phy);
index 4f70ef0b946dba1b7efa71ad9b0d6debb2f713c9..845372b025f6819298bf9ffbef86d2fd3a7e0d1e 100644 (file)
@@ -149,11 +149,8 @@ void inet_sock_destruct(struct sock *sk)
                pr_err("Attempt to release alive inet socket %p\n", sk);
                return;
        }
-       if (sk->sk_type == SOCK_STREAM) {
-               struct fastopen_queue *fastopenq =
-                       inet_csk(sk)->icsk_accept_queue.fastopenq;
-               kfree(fastopenq);
-       }
+       if (sk->sk_protocol == IPPROTO_TCP)
+               kfree(inet_csk(sk)->icsk_accept_queue.fastopenq);
 
        WARN_ON(atomic_read(&sk->sk_rmem_alloc));
        WARN_ON(atomic_read(&sk->sk_wmem_alloc));
index 77e87aff419ab105ef3ad3b5f852ef676b18a827..47800459e4cb341c395f54f2d161c300a112c1cf 100644 (file)
@@ -1225,7 +1225,7 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event,
        switch (event) {
        case NETDEV_CHANGEADDR:
                neigh_changeaddr(&arp_tbl, dev);
-               rt_cache_flush(dev_net(dev), 0);
+               rt_cache_flush(dev_net(dev));
                break;
        default:
                break;
index adf273f8ad2eb28a658321c68967bb2e6ccf25a0..7b00556e184bd29d804d8677a17660950428b8c6 100644 (file)
@@ -311,7 +311,7 @@ int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b)
 }
 
 static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
-                        int destroy, struct nlmsghdr *nlh, u32 pid)
+                        int destroy, struct nlmsghdr *nlh, u32 portid)
 {
        struct in_ifaddr *promote = NULL;
        struct in_ifaddr *ifa, *ifa1 = *ifap;
@@ -345,7 +345,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
                                inet_hash_remove(ifa);
                                *ifap1 = ifa->ifa_next;
 
-                               rtmsg_ifa(RTM_DELADDR, ifa, nlh, pid);
+                               rtmsg_ifa(RTM_DELADDR, ifa, nlh, portid);
                                blocking_notifier_call_chain(&inetaddr_chain,
                                                NETDEV_DOWN, ifa);
                                inet_free_ifa(ifa);
@@ -382,7 +382,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
           is valid, it will try to restore deleted routes... Grr.
           So that, this order is correct.
         */
-       rtmsg_ifa(RTM_DELADDR, ifa1, nlh, pid);
+       rtmsg_ifa(RTM_DELADDR, ifa1, nlh, portid);
        blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
 
        if (promote) {
@@ -395,7 +395,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
                }
 
                promote->ifa_flags &= ~IFA_F_SECONDARY;
-               rtmsg_ifa(RTM_NEWADDR, promote, nlh, pid);
+               rtmsg_ifa(RTM_NEWADDR, promote, nlh, portid);
                blocking_notifier_call_chain(&inetaddr_chain,
                                NETDEV_UP, promote);
                for (ifa = next_sec; ifa; ifa = ifa->ifa_next) {
@@ -417,7 +417,7 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
 }
 
 static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
-                            u32 pid)
+                            u32 portid)
 {
        struct in_device *in_dev = ifa->ifa_dev;
        struct in_ifaddr *ifa1, **ifap, **last_primary;
@@ -464,7 +464,7 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
        /* Send message first, then call notifier.
           Notifier will trigger FIB update, so that
           listeners of netlink will know about new ifaddr */
-       rtmsg_ifa(RTM_NEWADDR, ifa, nlh, pid);
+       rtmsg_ifa(RTM_NEWADDR, ifa, nlh, portid);
        blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
 
        return 0;
@@ -563,7 +563,7 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
                    !inet_ifa_match(nla_get_be32(tb[IFA_ADDRESS]), ifa)))
                        continue;
 
-               __inet_del_ifa(in_dev, ifap, 1, nlh, NETLINK_CB(skb).pid);
+               __inet_del_ifa(in_dev, ifap, 1, nlh, NETLINK_CB(skb).portid);
                return 0;
        }
 
@@ -649,7 +649,7 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
        if (IS_ERR(ifa))
                return PTR_ERR(ifa);
 
-       return __inet_insert_ifa(ifa, nlh, NETLINK_CB(skb).pid);
+       return __inet_insert_ifa(ifa, nlh, NETLINK_CB(skb).portid);
 }
 
 /*
@@ -1246,12 +1246,12 @@ static size_t inet_nlmsg_size(void)
 }
 
 static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
-                           u32 pid, u32 seq, int event, unsigned int flags)
+                           u32 portid, u32 seq, int event, unsigned int flags)
 {
        struct ifaddrmsg *ifm;
        struct nlmsghdr  *nlh;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*ifm), flags);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -1313,7 +1313,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
                                if (ip_idx < s_ip_idx)
                                        continue;
                                if (inet_fill_ifaddr(skb, ifa,
-                                            NETLINK_CB(cb->skb).pid,
+                                            NETLINK_CB(cb->skb).portid,
                                             cb->nlh->nlmsg_seq,
                                             RTM_NEWADDR, NLM_F_MULTI) <= 0) {
                                        rcu_read_unlock();
@@ -1335,7 +1335,7 @@ done:
 }
 
 static void rtmsg_ifa(int event, struct in_ifaddr *ifa, struct nlmsghdr *nlh,
-                     u32 pid)
+                     u32 portid)
 {
        struct sk_buff *skb;
        u32 seq = nlh ? nlh->nlmsg_seq : 0;
@@ -1347,14 +1347,14 @@ static void rtmsg_ifa(int event, struct in_ifaddr *ifa, struct nlmsghdr *nlh,
        if (skb == NULL)
                goto errout;
 
-       err = inet_fill_ifaddr(skb, ifa, pid, seq, event, 0);
+       err = inet_fill_ifaddr(skb, ifa, portid, seq, event, 0);
        if (err < 0) {
                /* -EMSGSIZE implies BUG in inet_nlmsg_size() */
                WARN_ON(err == -EMSGSIZE);
                kfree_skb(skb);
                goto errout;
        }
-       rtnl_notify(skb, net, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
+       rtnl_notify(skb, net, portid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
        return;
 errout:
        if (err < 0)
@@ -1500,7 +1500,7 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
                if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1 ||
                    i == IPV4_DEVCONF_ROUTE_LOCALNET - 1)
                        if ((new_value == 0) && (old_value != 0))
-                               rt_cache_flush(net, 0);
+                               rt_cache_flush(net);
        }
 
        return ret;
@@ -1534,7 +1534,7 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
                                dev_disable_lro(idev->dev);
                        }
                        rtnl_unlock();
-                       rt_cache_flush(net, 0);
+                       rt_cache_flush(net);
                }
        }
 
@@ -1551,7 +1551,7 @@ static int ipv4_doint_and_flush(ctl_table *ctl, int write,
        struct net *net = ctl->extra2;
 
        if (write && *valp != val)
-               rt_cache_flush(net, 0);
+               rt_cache_flush(net);
 
        return ret;
 }
index acdee325d972e8006994982639d47cbe5ad9e75e..68c93d1bb03adb9fef46ff264a783dad82a962ea 100644 (file)
@@ -148,7 +148,7 @@ static void fib_flush(struct net *net)
        }
 
        if (flushed)
-               rt_cache_flush(net, -1);
+               rt_cache_flush(net);
 }
 
 /*
@@ -557,7 +557,7 @@ static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
        cfg->fc_flags = rtm->rtm_flags;
        cfg->fc_nlflags = nlh->nlmsg_flags;
 
-       cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
+       cfg->fc_nlinfo.portid = NETLINK_CB(skb).portid;
        cfg->fc_nlinfo.nlh = nlh;
        cfg->fc_nlinfo.nl_net = net;
 
@@ -955,7 +955,7 @@ static void nl_fib_input(struct sk_buff *skb)
        struct fib_result_nl *frn;
        struct nlmsghdr *nlh;
        struct fib_table *tb;
-       u32 pid;
+       u32 portid;
 
        net = sock_net(skb->sk);
        nlh = nlmsg_hdr(skb);
@@ -973,10 +973,10 @@ static void nl_fib_input(struct sk_buff *skb)
 
        nl_fib_lookup(frn, tb);
 
-       pid = NETLINK_CB(skb).pid;      /* pid of sending process */
-       NETLINK_CB(skb).pid = 0;        /* from kernel */
+       portid = NETLINK_CB(skb).portid;      /* pid of sending process */
+       NETLINK_CB(skb).portid = 0;        /* from kernel */
        NETLINK_CB(skb).dst_group = 0;  /* unicast */
-       netlink_unicast(net->ipv4.fibnl, skb, pid, MSG_DONTWAIT);
+       netlink_unicast(net->ipv4.fibnl, skb, portid, MSG_DONTWAIT);
 }
 
 static int __net_init nl_fib_lookup_init(struct net *net)
@@ -986,7 +986,7 @@ static int __net_init nl_fib_lookup_init(struct net *net)
                .input  = nl_fib_input,
        };
 
-       sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, THIS_MODULE, &cfg);
+       sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, &cfg);
        if (sk == NULL)
                return -EAFNOSUPPORT;
        net->ipv4.fibnl = sk;
@@ -999,11 +999,11 @@ static void nl_fib_lookup_exit(struct net *net)
        net->ipv4.fibnl = NULL;
 }
 
-static void fib_disable_ip(struct net_device *dev, int force, int delay)
+static void fib_disable_ip(struct net_device *dev, int force)
 {
        if (fib_sync_down_dev(dev, force))
                fib_flush(dev_net(dev));
-       rt_cache_flush(dev_net(dev), delay);
+       rt_cache_flush(dev_net(dev));
        arp_ifdown(dev);
 }
 
@@ -1020,7 +1020,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
                fib_sync_up(dev);
 #endif
                atomic_inc(&net->ipv4.dev_addr_genid);
-               rt_cache_flush(dev_net(dev), -1);
+               rt_cache_flush(dev_net(dev));
                break;
        case NETDEV_DOWN:
                fib_del_ifaddr(ifa, NULL);
@@ -1029,9 +1029,9 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
                        /* Last address was deleted from this interface.
                         * Disable IP.
                         */
-                       fib_disable_ip(dev, 1, 0);
+                       fib_disable_ip(dev, 1);
                } else {
-                       rt_cache_flush(dev_net(dev), -1);
+                       rt_cache_flush(dev_net(dev));
                }
                break;
        }
@@ -1045,7 +1045,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
        struct net *net = dev_net(dev);
 
        if (event == NETDEV_UNREGISTER) {
-               fib_disable_ip(dev, 2, -1);
+               fib_disable_ip(dev, 2);
                rt_flush_dev(dev);
                return NOTIFY_DONE;
        }
@@ -1061,14 +1061,14 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
                fib_sync_up(dev);
 #endif
                atomic_inc(&net->ipv4.dev_addr_genid);
-               rt_cache_flush(net, -1);
+               rt_cache_flush(net);
                break;
        case NETDEV_DOWN:
-               fib_disable_ip(dev, 0, 0);
+               fib_disable_ip(dev, 0);
                break;
        case NETDEV_CHANGEMTU:
        case NETDEV_CHANGE:
-               rt_cache_flush(net, 0);
+               rt_cache_flush(net);
                break;
        }
        return NOTIFY_DONE;
index a83d74e498d23af8c104bc3d68eca5ca4a8ac228..274309d3aded0ffbf351dbf5f4ad128d87ff5a0b 100644 (file)
@@ -259,7 +259,7 @@ static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule)
 
 static void fib4_rule_flush_cache(struct fib_rules_ops *ops)
 {
-       rt_cache_flush(ops->fro_net, -1);
+       rt_cache_flush(ops->fro_net);
 }
 
 static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = {
index da80dc14cc76f51cb79e5c8042173396c036051e..3509065e409ab2782fe23cc8a174e369f0da501d 100644 (file)
@@ -391,7 +391,7 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
        if (skb == NULL)
                goto errout;
 
-       err = fib_dump_info(skb, info->pid, seq, event, tb_id,
+       err = fib_dump_info(skb, info->portid, seq, event, tb_id,
                            fa->fa_type, key, dst_len,
                            fa->fa_tos, fa->fa_info, nlm_flags);
        if (err < 0) {
@@ -400,7 +400,7 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
                kfree_skb(skb);
                goto errout;
        }
-       rtnl_notify(skb, info->nl_net, info->pid, RTNLGRP_IPV4_ROUTE,
+       rtnl_notify(skb, info->nl_net, info->portid, RTNLGRP_IPV4_ROUTE,
                    info->nlh, GFP_KERNEL);
        return;
 errout:
@@ -989,14 +989,14 @@ failure:
        return ERR_PTR(err);
 }
 
-int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
+int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
                  u32 tb_id, u8 type, __be32 dst, int dst_len, u8 tos,
                  struct fib_info *fi, unsigned int flags)
 {
        struct nlmsghdr *nlh;
        struct rtmsg *rtm;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*rtm), flags);
        if (nlh == NULL)
                return -EMSGSIZE;
 
index 3c820dae235e4e55fca8a2e9c0598ac3be5b6673..31d771ca9a709f71328c1734433cecba1fde40fd 100644 (file)
@@ -1286,7 +1286,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
 
                        fib_release_info(fi_drop);
                        if (state & FA_S_ACCESSED)
-                               rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+                               rt_cache_flush(cfg->fc_nlinfo.nl_net);
                        rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
                                tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
 
@@ -1333,7 +1333,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
        list_add_tail_rcu(&new_fa->fa_list,
                          (fa ? &fa->fa_list : fa_head));
 
-       rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+       rt_cache_flush(cfg->fc_nlinfo.nl_net);
        rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id,
                  &cfg->fc_nlinfo, 0);
 succeeded:
@@ -1711,7 +1711,7 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
                trie_leaf_remove(t, l);
 
        if (fa->fa_state & FA_S_ACCESSED)
-               rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+               rt_cache_flush(cfg->fc_nlinfo.nl_net);
 
        fib_release_info(fa->fa_info);
        alias_free_mem_rcu(fa);
@@ -1873,7 +1873,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah,
                        continue;
                }
 
-               if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid,
+               if (fib_dump_info(skb, NETLINK_CB(cb->skb).portid,
                                  cb->nlh->nlmsg_seq,
                                  RTM_NEWROUTE,
                                  tb->tb_id,
index 0b5580c69f2d46b5d2c49bcd0bcbb220439544ff..3479b98a00a701a1a8f6f650303fd6248eea9a60 100644 (file)
@@ -815,14 +815,15 @@ static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
        return 1;
 }
 
-static void igmp_heard_report(struct in_device *in_dev, __be32 group)
+/* return true if packet was dropped */
+static bool igmp_heard_report(struct in_device *in_dev, __be32 group)
 {
        struct ip_mc_list *im;
 
        /* Timers are only set for non-local groups */
 
        if (group == IGMP_ALL_HOSTS)
-               return;
+               return false;
 
        rcu_read_lock();
        for_each_pmc_rcu(in_dev, im) {
@@ -832,9 +833,11 @@ static void igmp_heard_report(struct in_device *in_dev, __be32 group)
                }
        }
        rcu_read_unlock();
+       return false;
 }
 
-static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
+/* return true if packet was dropped */
+static bool igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
        int len)
 {
        struct igmphdr          *ih = igmp_hdr(skb);
@@ -866,7 +869,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
                /* clear deleted report items */
                igmpv3_clear_delrec(in_dev);
        } else if (len < 12) {
-               return; /* ignore bogus packet; freed by caller */
+               return true;    /* ignore bogus packet; freed by caller */
        } else if (IGMP_V1_SEEN(in_dev)) {
                /* This is a v3 query with v1 queriers present */
                max_delay = IGMP_Query_Response_Interval;
@@ -883,13 +886,13 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
                        max_delay = 1;  /* can't mod w/ 0 */
        } else { /* v3 */
                if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)))
-                       return;
+                       return true;
 
                ih3 = igmpv3_query_hdr(skb);
                if (ih3->nsrcs) {
                        if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)
                                           + ntohs(ih3->nsrcs)*sizeof(__be32)))
-                               return;
+                               return true;
                        ih3 = igmpv3_query_hdr(skb);
                }
 
@@ -901,9 +904,9 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
                        in_dev->mr_qrv = ih3->qrv;
                if (!group) { /* general query */
                        if (ih3->nsrcs)
-                               return; /* no sources allowed */
+                               return false;   /* no sources allowed */
                        igmp_gq_start_timer(in_dev);
-                       return;
+                       return false;
                }
                /* mark sources to include, if group & source-specific */
                mark = ih3->nsrcs != 0;
@@ -939,6 +942,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
                        igmp_mod_timer(im, max_delay);
        }
        rcu_read_unlock();
+       return false;
 }
 
 /* called in rcu_read_lock() section */
@@ -948,6 +952,7 @@ int igmp_rcv(struct sk_buff *skb)
        struct igmphdr *ih;
        struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
        int len = skb->len;
+       bool dropped = true;
 
        if (in_dev == NULL)
                goto drop;
@@ -969,7 +974,7 @@ int igmp_rcv(struct sk_buff *skb)
        ih = igmp_hdr(skb);
        switch (ih->type) {
        case IGMP_HOST_MEMBERSHIP_QUERY:
-               igmp_heard_query(in_dev, skb, len);
+               dropped = igmp_heard_query(in_dev, skb, len);
                break;
        case IGMP_HOST_MEMBERSHIP_REPORT:
        case IGMPV2_HOST_MEMBERSHIP_REPORT:
@@ -979,7 +984,7 @@ int igmp_rcv(struct sk_buff *skb)
                /* don't rely on MC router hearing unicast reports */
                if (skb->pkt_type == PACKET_MULTICAST ||
                    skb->pkt_type == PACKET_BROADCAST)
-                       igmp_heard_report(in_dev, ih->group);
+                       dropped = igmp_heard_report(in_dev, ih->group);
                break;
        case IGMP_PIM:
 #ifdef CONFIG_IP_PIMSM_V1
@@ -997,7 +1002,10 @@ int igmp_rcv(struct sk_buff *skb)
        }
 
 drop:
-       kfree_skb(skb);
+       if (dropped)
+               kfree_skb(skb);
+       else
+               consume_skb(skb);
        return 0;
 }
 
index 8464b79c493f84f61c499d00e99c0eea0412a368..f0c5b9c1a95714e2e206cf6cd178a90626271fcc 100644 (file)
@@ -314,7 +314,7 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err)
        newsk = req->sk;
 
        sk_acceptq_removed(sk);
-       if (sk->sk_type == SOCK_STREAM && queue->fastopenq != NULL) {
+       if (sk->sk_protocol == IPPROTO_TCP && queue->fastopenq != NULL) {
                spin_lock_bh(&queue->fastopenq->lock);
                if (tcp_rsk(req)->listener) {
                        /* We are still waiting for the final ACK from 3WHS
@@ -775,7 +775,7 @@ void inet_csk_listen_stop(struct sock *sk)
 
                percpu_counter_inc(sk->sk_prot->orphan_count);
 
-               if (sk->sk_type == SOCK_STREAM && tcp_rsk(req)->listener) {
+               if (sk->sk_protocol == IPPROTO_TCP && tcp_rsk(req)->listener) {
                        BUG_ON(tcp_sk(child)->fastopen_rsk != req);
                        BUG_ON(sk != tcp_rsk(req)->listener);
 
index 8bc005b1435f5109269a6057ad96d7c9985574d5..535584c00f9118fe33a17e79b858e66935f424f9 100644 (file)
@@ -70,7 +70,7 @@ static inline void inet_diag_unlock_handler(
 int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
                              struct sk_buff *skb, struct inet_diag_req_v2 *req,
                              struct user_namespace *user_ns,                   
-                             u32 pid, u32 seq, u16 nlmsg_flags,
+                             u32 portid, u32 seq, u16 nlmsg_flags,
                              const struct nlmsghdr *unlh)
 {
        const struct inet_sock *inet = inet_sk(sk);
@@ -84,7 +84,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
        handler = inet_diag_table[req->sdiag_protocol];
        BUG_ON(handler == NULL);
 
-       nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r),
+       nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r),
                        nlmsg_flags);
        if (!nlh)
                return -EMSGSIZE;
@@ -201,23 +201,23 @@ EXPORT_SYMBOL_GPL(inet_sk_diag_fill);
 static int inet_csk_diag_fill(struct sock *sk,
                              struct sk_buff *skb, struct inet_diag_req_v2 *req,
                              struct user_namespace *user_ns,
-                             u32 pid, u32 seq, u16 nlmsg_flags,
+                             u32 portid, u32 seq, u16 nlmsg_flags,
                              const struct nlmsghdr *unlh)
 {
        return inet_sk_diag_fill(sk, inet_csk(sk),
-                       skb, req, user_ns, pid, seq, nlmsg_flags, unlh);
+                       skb, req, user_ns, portid, seq, nlmsg_flags, unlh);
 }
 
 static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
                               struct sk_buff *skb, struct inet_diag_req_v2 *req,
-                              u32 pid, u32 seq, u16 nlmsg_flags,
+                              u32 portid, u32 seq, u16 nlmsg_flags,
                               const struct nlmsghdr *unlh)
 {
        long tmo;
        struct inet_diag_msg *r;
        struct nlmsghdr *nlh;
 
-       nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r),
+       nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r),
                        nlmsg_flags);
        if (!nlh)
                return -EMSGSIZE;
@@ -260,14 +260,14 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
 static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
                        struct inet_diag_req_v2 *r,
                        struct user_namespace *user_ns,
-                       u32 pid, u32 seq, u16 nlmsg_flags,
+                       u32 portid, u32 seq, u16 nlmsg_flags,
                        const struct nlmsghdr *unlh)
 {
        if (sk->sk_state == TCP_TIME_WAIT)
                return inet_twsk_diag_fill((struct inet_timewait_sock *)sk,
-                                          skb, r, pid, seq, nlmsg_flags,
+                                          skb, r, portid, seq, nlmsg_flags,
                                           unlh);
-       return inet_csk_diag_fill(sk, skb, r, user_ns, pid, seq, nlmsg_flags, unlh);
+       return inet_csk_diag_fill(sk, skb, r, user_ns, portid, seq, nlmsg_flags, unlh);
 }
 
 int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb,
@@ -316,14 +316,14 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s
 
        err = sk_diag_fill(sk, rep, req,
                           sk_user_ns(NETLINK_CB(in_skb).ssk),
-                          NETLINK_CB(in_skb).pid,
+                          NETLINK_CB(in_skb).portid,
                           nlh->nlmsg_seq, 0, nlh);
        if (err < 0) {
                WARN_ON(err == -EMSGSIZE);
                nlmsg_free(rep);
                goto out;
        }
-       err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).pid,
+       err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid,
                              MSG_DONTWAIT);
        if (err > 0)
                err = 0;
@@ -557,7 +557,7 @@ static int inet_csk_diag_dump(struct sock *sk,
 
        return inet_csk_diag_fill(sk, skb, r,
                                  sk_user_ns(NETLINK_CB(cb->skb).ssk),
-                                 NETLINK_CB(cb->skb).pid,
+                                 NETLINK_CB(cb->skb).portid,
                                  cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
 }
 
@@ -592,14 +592,14 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
        }
 
        return inet_twsk_diag_fill(tw, skb, r,
-                                  NETLINK_CB(cb->skb).pid,
+                                  NETLINK_CB(cb->skb).portid,
                                   cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
 }
 
 static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
                              struct request_sock *req,
                              struct user_namespace *user_ns,
-                             u32 pid, u32 seq,
+                             u32 portid, u32 seq,
                              const struct nlmsghdr *unlh)
 {
        const struct inet_request_sock *ireq = inet_rsk(req);
@@ -608,7 +608,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
        struct nlmsghdr *nlh;
        long tmo;
 
-       nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r),
+       nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r),
                        NLM_F_MULTI);
        if (!nlh)
                return -EMSGSIZE;
@@ -711,7 +711,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
 
                        err = inet_diag_fill_req(skb, sk, req,
                                               sk_user_ns(NETLINK_CB(cb->skb).ssk),
-                                              NETLINK_CB(cb->skb).pid,
+                                              NETLINK_CB(cb->skb).portid,
                                               cb->nlh->nlmsg_seq, cb->nlh);
                        if (err < 0) {
                                cb->args[3] = j + 1;
index 8aa7a4cf9139285fa955199946d6d9c7d3b5b545..1daa95c2a0bad8e532181dc4d67d4aead0f3671f 100644 (file)
@@ -626,7 +626,7 @@ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c)
                        e->error = -ETIMEDOUT;
                        memset(&e->msg, 0, sizeof(e->msg));
 
-                       rtnl_unicast(skb, net, NETLINK_CB(skb).pid);
+                       rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
                } else {
                        kfree_skb(skb);
                }
@@ -870,7 +870,7 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt,
                                memset(&e->msg, 0, sizeof(e->msg));
                        }
 
-                       rtnl_unicast(skb, net, NETLINK_CB(skb).pid);
+                       rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
                } else {
                        ip_mr_forward(net, mrt, skb, c, 0);
                }
@@ -2117,12 +2117,12 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb,
 }
 
 static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
-                           u32 pid, u32 seq, struct mfc_cache *c)
+                           u32 portid, u32 seq, struct mfc_cache *c)
 {
        struct nlmsghdr *nlh;
        struct rtmsg *rtm;
 
-       nlh = nlmsg_put(skb, pid, seq, RTM_NEWROUTE, sizeof(*rtm), NLM_F_MULTI);
+       nlh = nlmsg_put(skb, portid, seq, RTM_NEWROUTE, sizeof(*rtm), NLM_F_MULTI);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -2176,7 +2176,7 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
                                if (e < s_e)
                                        goto next_entry;
                                if (ipmr_fill_mroute(mrt, skb,
-                                                    NETLINK_CB(cb->skb).pid,
+                                                    NETLINK_CB(cb->skb).portid,
                                                     cb->nlh->nlmsg_seq,
                                                     mfc) < 0)
                                        goto done;
index 1109f7f6c25433d64515180eb6c9ff599dcef0f0..b5ef3cba225046fdc142bf5029954e02fcb08df1 100644 (file)
@@ -396,8 +396,7 @@ static int __init ulog_tg_init(void)
        for (i = 0; i < ULOG_MAXNLGROUPS; i++)
                setup_timer(&ulog_buffers[i].timer, ulog_timer, i);
 
-       nflognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
-                                       THIS_MODULE, &cfg);
+       nflognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, &cfg);
        if (!nflognl)
                return -ENOMEM;
 
index dc9549b5eb1c8be11c6997e460ffb517a8b06bb3..940f4f4cb2012aef8a3de80da28f0ae647271a49 100644 (file)
@@ -447,27 +447,9 @@ static inline bool rt_is_expired(const struct rtable *rth)
        return rth->rt_genid != rt_genid(dev_net(rth->dst.dev));
 }
 
-/*
- * Perturbation of rt_genid by a small quantity [1..256]
- * Using 8 bits of shuffling ensure we can call rt_cache_invalidate()
- * many times (2^24) without giving recent rt_genid.
- * Jenkins hash is strong enough that litle changes of rt_genid are OK.
- */
-static void rt_cache_invalidate(struct net *net)
-{
-       unsigned char shuffle;
-
-       get_random_bytes(&shuffle, sizeof(shuffle));
-       atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
-}
-
-/*
- * delay < 0  : invalidate cache (fast : entries will be deleted later)
- * delay >= 0 : invalidate & flush cache (can be long)
- */
-void rt_cache_flush(struct net *net, int delay)
+void rt_cache_flush(struct net *net)
 {
-       rt_cache_invalidate(net);
+       atomic_inc(&net->ipv4.rt_genid);
 }
 
 static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
@@ -2154,7 +2136,7 @@ struct rtable *ip_route_output_flow(struct net *net, struct flowi4 *flp4,
 EXPORT_SYMBOL_GPL(ip_route_output_flow);
 
 static int rt_fill_info(struct net *net,  __be32 dst, __be32 src,
-                       struct flowi4 *fl4, struct sk_buff *skb, u32 pid,
+                       struct flowi4 *fl4, struct sk_buff *skb, u32 portid,
                        u32 seq, int event, int nowait, unsigned int flags)
 {
        struct rtable *rt = skb_rtable(skb);
@@ -2164,7 +2146,7 @@ static int rt_fill_info(struct net *net,  __be32 dst, __be32 src,
        u32 error;
        u32 metrics[RTAX_MAX];
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*r), flags);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -2324,12 +2306,12 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
                rt->rt_flags |= RTCF_NOTIFY;
 
        err = rt_fill_info(net, dst, src, &fl4, skb,
-                          NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
+                          NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
                           RTM_NEWROUTE, 0, 0);
        if (err <= 0)
                goto errout_free;
 
-       err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
+       err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
 errout:
        return err;
 
@@ -2345,7 +2327,7 @@ int ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb)
 
 void ip_rt_multicast_event(struct in_device *in_dev)
 {
-       rt_cache_flush(dev_net(in_dev->dev), 0);
+       rt_cache_flush(dev_net(in_dev->dev));
 }
 
 #ifdef CONFIG_SYSCTL
@@ -2354,16 +2336,7 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
                                        size_t *lenp, loff_t *ppos)
 {
        if (write) {
-               int flush_delay;
-               ctl_table ctl;
-               struct net *net;
-
-               memcpy(&ctl, __ctl, sizeof(ctl));
-               ctl.data = &flush_delay;
-               proc_dointvec(&ctl, write, buffer, lenp, ppos);
-
-               net = (struct net *)__ctl->extra1;
-               rt_cache_flush(net, flush_delay);
+               rt_cache_flush((struct net *)__ctl->extra1);
                return 0;
        }
 
@@ -2533,8 +2506,7 @@ static __net_initdata struct pernet_operations sysctl_route_ops = {
 
 static __net_init int rt_genid_init(struct net *net)
 {
-       get_random_bytes(&net->ipv4.rt_genid,
-                        sizeof(net->ipv4.rt_genid));
+       atomic_set(&net->ipv4.rt_genid, 0);
        get_random_bytes(&net->ipv4.dev_addr_genid,
                         sizeof(net->ipv4.dev_addr_genid));
        return 0;
index 0abe67bb4d3a3adb0d9df820b1fe64b6ef9da591..4c752a6e0bcd91b0b932b483a2b9f988908c04a2 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/init.h>
 #include <linux/tcp.h>
 #include <linux/hash.h>
+#include <linux/tcp_metrics.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/net_namespace.h>
 #include <net/ipv6.h>
 #include <net/dst.h>
 #include <net/tcp.h>
+#include <net/genetlink.h>
 
 int sysctl_tcp_nometrics_save __read_mostly;
 
-enum tcp_metric_index {
-       TCP_METRIC_RTT,
-       TCP_METRIC_RTTVAR,
-       TCP_METRIC_SSTHRESH,
-       TCP_METRIC_CWND,
-       TCP_METRIC_REORDERING,
-
-       /* Always last.  */
-       TCP_METRIC_MAX,
-};
-
 struct tcp_fastopen_metrics {
        u16     mss;
        u16     syn_loss:10;            /* Recurring Fast Open SYN losses */
@@ -45,8 +36,10 @@ struct tcp_metrics_block {
        u32                             tcpm_ts;
        u32                             tcpm_ts_stamp;
        u32                             tcpm_lock;
-       u32                             tcpm_vals[TCP_METRIC_MAX];
+       u32                             tcpm_vals[TCP_METRIC_MAX + 1];
        struct tcp_fastopen_metrics     tcpm_fastopen;
+
+       struct rcu_head                 rcu_head;
 };
 
 static bool tcp_metric_locked(struct tcp_metrics_block *tm,
@@ -690,6 +683,325 @@ void tcp_fastopen_cache_set(struct sock *sk, u16 mss,
        rcu_read_unlock();
 }
 
+static struct genl_family tcp_metrics_nl_family = {
+       .id             = GENL_ID_GENERATE,
+       .hdrsize        = 0,
+       .name           = TCP_METRICS_GENL_NAME,
+       .version        = TCP_METRICS_GENL_VERSION,
+       .maxattr        = TCP_METRICS_ATTR_MAX,
+       .netnsok        = true,
+};
+
+static struct nla_policy tcp_metrics_nl_policy[TCP_METRICS_ATTR_MAX + 1] = {
+       [TCP_METRICS_ATTR_ADDR_IPV4]    = { .type = NLA_U32, },
+       [TCP_METRICS_ATTR_ADDR_IPV6]    = { .type = NLA_BINARY,
+                                           .len = sizeof(struct in6_addr), },
+       /* Following attributes are not received for GET/DEL,
+        * we keep them for reference
+        */
+#if 0
+       [TCP_METRICS_ATTR_AGE]          = { .type = NLA_MSECS, },
+       [TCP_METRICS_ATTR_TW_TSVAL]     = { .type = NLA_U32, },
+       [TCP_METRICS_ATTR_TW_TS_STAMP]  = { .type = NLA_S32, },
+       [TCP_METRICS_ATTR_VALS]         = { .type = NLA_NESTED, },
+       [TCP_METRICS_ATTR_FOPEN_MSS]    = { .type = NLA_U16, },
+       [TCP_METRICS_ATTR_FOPEN_SYN_DROPS]      = { .type = NLA_U16, },
+       [TCP_METRICS_ATTR_FOPEN_SYN_DROP_TS]    = { .type = NLA_MSECS, },
+       [TCP_METRICS_ATTR_FOPEN_COOKIE] = { .type = NLA_BINARY,
+                                           .len = TCP_FASTOPEN_COOKIE_MAX, },
+#endif
+};
+
+/* Add attributes, caller cancels its header on failure */
+static int tcp_metrics_fill_info(struct sk_buff *msg,
+                                struct tcp_metrics_block *tm)
+{
+       struct nlattr *nest;
+       int i;
+
+       switch (tm->tcpm_addr.family) {
+       case AF_INET:
+               if (nla_put_be32(msg, TCP_METRICS_ATTR_ADDR_IPV4,
+                               tm->tcpm_addr.addr.a4) < 0)
+                       goto nla_put_failure;
+               break;
+       case AF_INET6:
+               if (nla_put(msg, TCP_METRICS_ATTR_ADDR_IPV6, 16,
+                           tm->tcpm_addr.addr.a6) < 0)
+                       goto nla_put_failure;
+               break;
+       default:
+               return -EAFNOSUPPORT;
+       }
+
+       if (nla_put_msecs(msg, TCP_METRICS_ATTR_AGE,
+                         jiffies - tm->tcpm_stamp) < 0)
+               goto nla_put_failure;
+       if (tm->tcpm_ts_stamp) {
+               if (nla_put_s32(msg, TCP_METRICS_ATTR_TW_TS_STAMP,
+                               (s32) (get_seconds() - tm->tcpm_ts_stamp)) < 0)
+                       goto nla_put_failure;
+               if (nla_put_u32(msg, TCP_METRICS_ATTR_TW_TSVAL,
+                               tm->tcpm_ts) < 0)
+                       goto nla_put_failure;
+       }
+
+       {
+               int n = 0;
+
+               nest = nla_nest_start(msg, TCP_METRICS_ATTR_VALS);
+               if (!nest)
+                       goto nla_put_failure;
+               for (i = 0; i < TCP_METRIC_MAX + 1; i++) {
+                       if (!tm->tcpm_vals[i])
+                               continue;
+                       if (nla_put_u32(msg, i + 1, tm->tcpm_vals[i]) < 0)
+                               goto nla_put_failure;
+                       n++;
+               }
+               if (n)
+                       nla_nest_end(msg, nest);
+               else
+                       nla_nest_cancel(msg, nest);
+       }
+
+       {
+               struct tcp_fastopen_metrics tfom_copy[1], *tfom;
+               unsigned int seq;
+
+               do {
+                       seq = read_seqbegin(&fastopen_seqlock);
+                       tfom_copy[0] = tm->tcpm_fastopen;
+               } while (read_seqretry(&fastopen_seqlock, seq));
+
+               tfom = tfom_copy;
+               if (tfom->mss &&
+                   nla_put_u16(msg, TCP_METRICS_ATTR_FOPEN_MSS,
+                               tfom->mss) < 0)
+                       goto nla_put_failure;
+               if (tfom->syn_loss &&
+                   (nla_put_u16(msg, TCP_METRICS_ATTR_FOPEN_SYN_DROPS,
+                               tfom->syn_loss) < 0 ||
+                    nla_put_msecs(msg, TCP_METRICS_ATTR_FOPEN_SYN_DROP_TS,
+                               jiffies - tfom->last_syn_loss) < 0))
+                       goto nla_put_failure;
+               if (tfom->cookie.len > 0 &&
+                   nla_put(msg, TCP_METRICS_ATTR_FOPEN_COOKIE,
+                           tfom->cookie.len, tfom->cookie.val) < 0)
+                       goto nla_put_failure;
+       }
+
+       return 0;
+
+nla_put_failure:
+       return -EMSGSIZE;
+}
+
+static int tcp_metrics_dump_info(struct sk_buff *skb,
+                                struct netlink_callback *cb,
+                                struct tcp_metrics_block *tm)
+{
+       void *hdr;
+
+       hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
+                         &tcp_metrics_nl_family, NLM_F_MULTI,
+                         TCP_METRICS_CMD_GET);
+       if (!hdr)
+               return -EMSGSIZE;
+
+       if (tcp_metrics_fill_info(skb, tm) < 0)
+               goto nla_put_failure;
+
+       return genlmsg_end(skb, hdr);
+
+nla_put_failure:
+       genlmsg_cancel(skb, hdr);
+       return -EMSGSIZE;
+}
+
+static int tcp_metrics_nl_dump(struct sk_buff *skb,
+                              struct netlink_callback *cb)
+{
+       struct net *net = sock_net(skb->sk);
+       unsigned int max_rows = 1U << net->ipv4.tcp_metrics_hash_log;
+       unsigned int row, s_row = cb->args[0];
+       int s_col = cb->args[1], col = s_col;
+
+       for (row = s_row; row < max_rows; row++, s_col = 0) {
+               struct tcp_metrics_block *tm;
+               struct tcpm_hash_bucket *hb = net->ipv4.tcp_metrics_hash + row;
+
+               rcu_read_lock();
+               for (col = 0, tm = rcu_dereference(hb->chain); tm;
+                    tm = rcu_dereference(tm->tcpm_next), col++) {
+                       if (col < s_col)
+                               continue;
+                       if (tcp_metrics_dump_info(skb, cb, tm) < 0) {
+                               rcu_read_unlock();
+                               goto done;
+                       }
+               }
+               rcu_read_unlock();
+       }
+
+done:
+       cb->args[0] = row;
+       cb->args[1] = col;
+       return skb->len;
+}
+
+static int parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr,
+                        unsigned int *hash, int optional)
+{
+       struct nlattr *a;
+
+       a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV4];
+       if (a) {
+               addr->family = AF_INET;
+               addr->addr.a4 = nla_get_be32(a);
+               *hash = (__force unsigned int) addr->addr.a4;
+               return 0;
+       }
+       a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV6];
+       if (a) {
+               if (nla_len(a) != sizeof(sizeof(struct in6_addr)))
+                       return -EINVAL;
+               addr->family = AF_INET6;
+               memcpy(addr->addr.a6, nla_data(a), sizeof(addr->addr.a6));
+               *hash = ipv6_addr_hash((struct in6_addr *) addr->addr.a6);
+               return 0;
+       }
+       return optional ? 1 : -EAFNOSUPPORT;
+}
+
+static int tcp_metrics_nl_cmd_get(struct sk_buff *skb, struct genl_info *info)
+{
+       struct tcp_metrics_block *tm;
+       struct inetpeer_addr addr;
+       unsigned int hash;
+       struct sk_buff *msg;
+       struct net *net = genl_info_net(info);
+       void *reply;
+       int ret;
+
+       ret = parse_nl_addr(info, &addr, &hash, 0);
+       if (ret < 0)
+               return ret;
+
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+       if (!msg)
+               return -ENOMEM;
+
+       reply = genlmsg_put_reply(msg, info, &tcp_metrics_nl_family, 0,
+                                 info->genlhdr->cmd);
+       if (!reply)
+               goto nla_put_failure;
+
+       hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log);
+       ret = -ESRCH;
+       rcu_read_lock();
+       for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
+            tm = rcu_dereference(tm->tcpm_next)) {
+               if (addr_same(&tm->tcpm_addr, &addr)) {
+                       ret = tcp_metrics_fill_info(msg, tm);
+                       break;
+               }
+       }
+       rcu_read_unlock();
+       if (ret < 0)
+               goto out_free;
+
+       genlmsg_end(msg, reply);
+       return genlmsg_reply(msg, info);
+
+nla_put_failure:
+       ret = -EMSGSIZE;
+
+out_free:
+       nlmsg_free(msg);
+       return ret;
+}
+
+#define deref_locked_genl(p)   \
+       rcu_dereference_protected(p, lockdep_genl_is_held() && \
+                                    lockdep_is_held(&tcp_metrics_lock))
+
+#define deref_genl(p)  rcu_dereference_protected(p, lockdep_genl_is_held())
+
+static int tcp_metrics_flush_all(struct net *net)
+{
+       unsigned int max_rows = 1U << net->ipv4.tcp_metrics_hash_log;
+       struct tcpm_hash_bucket *hb = net->ipv4.tcp_metrics_hash;
+       struct tcp_metrics_block *tm;
+       unsigned int row;
+
+       for (row = 0; row < max_rows; row++, hb++) {
+               spin_lock_bh(&tcp_metrics_lock);
+               tm = deref_locked_genl(hb->chain);
+               if (tm)
+                       hb->chain = NULL;
+               spin_unlock_bh(&tcp_metrics_lock);
+               while (tm) {
+                       struct tcp_metrics_block *next;
+
+                       next = deref_genl(tm->tcpm_next);
+                       kfree_rcu(tm, rcu_head);
+                       tm = next;
+               }
+       }
+       return 0;
+}
+
+static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
+{
+       struct tcpm_hash_bucket *hb;
+       struct tcp_metrics_block *tm;
+       struct tcp_metrics_block __rcu **pp;
+       struct inetpeer_addr addr;
+       unsigned int hash;
+       struct net *net = genl_info_net(info);
+       int ret;
+
+       ret = parse_nl_addr(info, &addr, &hash, 1);
+       if (ret < 0)
+               return ret;
+       if (ret > 0)
+               return tcp_metrics_flush_all(net);
+
+       hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log);
+       hb = net->ipv4.tcp_metrics_hash + hash;
+       pp = &hb->chain;
+       spin_lock_bh(&tcp_metrics_lock);
+       for (tm = deref_locked_genl(*pp); tm;
+            pp = &tm->tcpm_next, tm = deref_locked_genl(*pp)) {
+               if (addr_same(&tm->tcpm_addr, &addr)) {
+                       *pp = tm->tcpm_next;
+                       break;
+               }
+       }
+       spin_unlock_bh(&tcp_metrics_lock);
+       if (!tm)
+               return -ESRCH;
+       kfree_rcu(tm, rcu_head);
+       return 0;
+}
+
+static struct genl_ops tcp_metrics_nl_ops[] = {
+       {
+               .cmd = TCP_METRICS_CMD_GET,
+               .doit = tcp_metrics_nl_cmd_get,
+               .dumpit = tcp_metrics_nl_dump,
+               .policy = tcp_metrics_nl_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
+       {
+               .cmd = TCP_METRICS_CMD_DEL,
+               .doit = tcp_metrics_nl_cmd_del,
+               .policy = tcp_metrics_nl_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
+};
+
 static unsigned int tcpmhash_entries;
 static int __init set_tcpmhash_entries(char *str)
 {
@@ -753,5 +1065,21 @@ static __net_initdata struct pernet_operations tcp_net_metrics_ops = {
 
 void __init tcp_metrics_init(void)
 {
-       register_pernet_subsys(&tcp_net_metrics_ops);
+       int ret;
+
+       ret = register_pernet_subsys(&tcp_net_metrics_ops);
+       if (ret < 0)
+               goto cleanup;
+       ret = genl_register_family_with_ops(&tcp_metrics_nl_family,
+                                           tcp_metrics_nl_ops,
+                                           ARRAY_SIZE(tcp_metrics_nl_ops));
+       if (ret < 0)
+               goto cleanup_subsys;
+       return;
+
+cleanup_subsys:
+       unregister_pernet_subsys(&tcp_net_metrics_ops);
+
+cleanup:
+       return;
 }
index d2f336ea82caa98cefdc6e84540fa784ea6703b7..505b30ad9182dc83e42e106b4bbaa507dd84f591 100644 (file)
@@ -26,7 +26,7 @@ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb,
 
        return inet_sk_diag_fill(sk, NULL, skb, req,
                        sk_user_ns(NETLINK_CB(cb->skb).ssk),
-                       NETLINK_CB(cb->skb).pid,
+                       NETLINK_CB(cb->skb).portid,
                        cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
 }
 
@@ -72,14 +72,14 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
 
        err = inet_sk_diag_fill(sk, NULL, rep, req,
                           sk_user_ns(NETLINK_CB(in_skb).ssk),
-                          NETLINK_CB(in_skb).pid,
+                          NETLINK_CB(in_skb).portid,
                           nlh->nlmsg_seq, 0, nlh);
        if (err < 0) {
                WARN_ON(err == -EMSGSIZE);
                kfree_skb(rep);
                goto out;
        }
-       err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).pid,
+       err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid,
                              MSG_DONTWAIT);
        if (err > 0)
                err = 0;
index 572cb660837bc62367a80006196932f5ee162aca..1237d5d037d82750b9aad892446f3f6be620abdf 100644 (file)
@@ -3534,12 +3534,12 @@ static inline int inet6_ifaddr_msgsize(void)
 }
 
 static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
-                            u32 pid, u32 seq, int event, unsigned int flags)
+                            u32 portid, u32 seq, int event, unsigned int flags)
 {
        struct nlmsghdr  *nlh;
        u32 preferred, valid;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -3577,7 +3577,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
 }
 
 static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
-                               u32 pid, u32 seq, int event, u16 flags)
+                               u32 portid, u32 seq, int event, u16 flags)
 {
        struct nlmsghdr  *nlh;
        u8 scope = RT_SCOPE_UNIVERSE;
@@ -3586,7 +3586,7 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
        if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
                scope = RT_SCOPE_SITE;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -3602,7 +3602,7 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
 }
 
 static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
-                               u32 pid, u32 seq, int event, unsigned int flags)
+                               u32 portid, u32 seq, int event, unsigned int flags)
 {
        struct nlmsghdr  *nlh;
        u8 scope = RT_SCOPE_UNIVERSE;
@@ -3611,7 +3611,7 @@ static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
        if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
                scope = RT_SCOPE_SITE;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -3652,7 +3652,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
                        if (++ip_idx < s_ip_idx)
                                continue;
                        err = inet6_fill_ifaddr(skb, ifa,
-                                               NETLINK_CB(cb->skb).pid,
+                                               NETLINK_CB(cb->skb).portid,
                                                cb->nlh->nlmsg_seq,
                                                RTM_NEWADDR,
                                                NLM_F_MULTI);
@@ -3668,7 +3668,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
                        if (ip_idx < s_ip_idx)
                                continue;
                        err = inet6_fill_ifmcaddr(skb, ifmca,
-                                                 NETLINK_CB(cb->skb).pid,
+                                                 NETLINK_CB(cb->skb).portid,
                                                  cb->nlh->nlmsg_seq,
                                                  RTM_GETMULTICAST,
                                                  NLM_F_MULTI);
@@ -3683,7 +3683,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
                        if (ip_idx < s_ip_idx)
                                continue;
                        err = inet6_fill_ifacaddr(skb, ifaca,
-                                                 NETLINK_CB(cb->skb).pid,
+                                                 NETLINK_CB(cb->skb).portid,
                                                  cb->nlh->nlmsg_seq,
                                                  RTM_GETANYCAST,
                                                  NLM_F_MULTI);
@@ -3805,7 +3805,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
                goto errout_ifa;
        }
 
-       err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
+       err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).portid,
                                nlh->nlmsg_seq, RTM_NEWADDR, 0);
        if (err < 0) {
                /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
@@ -3813,7 +3813,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
                kfree_skb(skb);
                goto errout_ifa;
        }
-       err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
+       err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
 errout_ifa:
        in6_ifa_put(ifa);
 errout:
@@ -4015,14 +4015,14 @@ static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
 }
 
 static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
-                            u32 pid, u32 seq, int event, unsigned int flags)
+                            u32 portid, u32 seq, int event, unsigned int flags)
 {
        struct net_device *dev = idev->dev;
        struct ifinfomsg *hdr;
        struct nlmsghdr *nlh;
        void *protoinfo;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*hdr), flags);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -4080,7 +4080,7 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
                        if (!idev)
                                goto cont;
                        if (inet6_fill_ifinfo(skb, idev,
-                                             NETLINK_CB(cb->skb).pid,
+                                             NETLINK_CB(cb->skb).portid,
                                              cb->nlh->nlmsg_seq,
                                              RTM_NEWLINK, NLM_F_MULTI) <= 0)
                                goto out;
@@ -4128,14 +4128,14 @@ static inline size_t inet6_prefix_nlmsg_size(void)
 }
 
 static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
-                            struct prefix_info *pinfo, u32 pid, u32 seq,
+                            struct prefix_info *pinfo, u32 portid, u32 seq,
                             int event, unsigned int flags)
 {
        struct prefixmsg *pmsg;
        struct nlmsghdr *nlh;
        struct prefix_cacheinfo ci;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*pmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*pmsg), flags);
        if (nlh == NULL)
                return -EMSGSIZE;
 
index eb6a63632d3c1b6b2fab973588760053c4d9e3bb..0b0171570d176de19dd6ddd02f96597616394165 100644 (file)
@@ -470,10 +470,10 @@ static void ip6addrlbl_putmsg(struct nlmsghdr *nlh,
 static int ip6addrlbl_fill(struct sk_buff *skb,
                           struct ip6addrlbl_entry *p,
                           u32 lseq,
-                          u32 pid, u32 seq, int event,
+                          u32 portid, u32 seq, int event,
                           unsigned int flags)
 {
-       struct nlmsghdr *nlh = nlmsg_put(skb, pid, seq, event,
+       struct nlmsghdr *nlh = nlmsg_put(skb, portid, seq, event,
                                         sizeof(struct ifaddrlblmsg), flags);
        if (!nlh)
                return -EMSGSIZE;
@@ -503,7 +503,7 @@ static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
                    net_eq(ip6addrlbl_net(p), net)) {
                        if ((err = ip6addrlbl_fill(skb, p,
                                                   ip6addrlbl_table.seq,
-                                                  NETLINK_CB(cb->skb).pid,
+                                                  NETLINK_CB(cb->skb).portid,
                                                   cb->nlh->nlmsg_seq,
                                                   RTM_NEWADDRLABEL,
                                                   NLM_F_MULTI)) <= 0)
@@ -574,7 +574,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
        }
 
        err = ip6addrlbl_fill(skb, p, lseq,
-                             NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
+                             NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
                              RTM_NEWADDRLABEL, 0);
 
        ip6addrlbl_put(p);
@@ -585,7 +585,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
                goto out;
        }
 
-       err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
+       err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
 out:
        return err;
 }
index a4f6263fddca74c885ede0ee25e54fefdde0de16..3dd4a37488d53e3290578036b6b5d3c3d5dcee00 100644 (file)
@@ -123,16 +123,11 @@ static int ip6_finish_output2(struct sk_buff *skb)
                                skb->len);
        }
 
-       rcu_read_lock();
        rt = (struct rt6_info *) dst;
        neigh = rt->n;
-       if (neigh) {
-               int res = dst_neigh_output(dst, neigh, skb);
+       if (neigh)
+               return dst_neigh_output(dst, neigh, skb);
 
-               rcu_read_unlock();
-               return res;
-       }
-       rcu_read_unlock();
        IP6_INC_STATS_BH(dev_net(dst->dev),
                         ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
        kfree_skb(skb);
@@ -983,7 +978,6 @@ static int ip6_dst_lookup_tail(struct sock *sk,
         * dst entry and replace it instead with the
         * dst entry of the nexthop router
         */
-       rcu_read_lock();
        rt = (struct rt6_info *) *dst;
        n = rt->n;
        if (n && !(n->nud_state & NUD_VALID)) {
@@ -991,7 +985,6 @@ static int ip6_dst_lookup_tail(struct sock *sk,
                struct flowi6 fl_gw6;
                int redirect;
 
-               rcu_read_unlock();
                ifp = ipv6_get_ifaddr(net, &fl6->saddr,
                                      (*dst)->dev, 1);
 
@@ -1011,8 +1004,6 @@ static int ip6_dst_lookup_tail(struct sock *sk,
                        if ((err = (*dst)->error))
                                goto out_err_release;
                }
-       } else {
-               rcu_read_unlock();
        }
 #endif
 
index 4532973f0dd4fc8fd3467a81cc0a2ce0581c72f1..08ea3f0b6e55f9557ec1e919e77f1496ccb1fdf1 100644 (file)
@@ -838,7 +838,7 @@ static void ip6mr_destroy_unres(struct mr6_table *mrt, struct mfc6_cache *c)
                        nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
                        skb_trim(skb, nlh->nlmsg_len);
                        ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -ETIMEDOUT;
-                       rtnl_unicast(skb, net, NETLINK_CB(skb).pid);
+                       rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
                } else
                        kfree_skb(skb);
        }
@@ -1052,7 +1052,7 @@ static void ip6mr_cache_resolve(struct net *net, struct mr6_table *mrt,
                                skb_trim(skb, nlh->nlmsg_len);
                                ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -EMSGSIZE;
                        }
-                       rtnl_unicast(skb, net, NETLINK_CB(skb).pid);
+                       rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
                } else
                        ip6_mr_forward(net, mrt, skb, c);
        }
@@ -2202,12 +2202,12 @@ int ip6mr_get_route(struct net *net,
 }
 
 static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
-                            u32 pid, u32 seq, struct mfc6_cache *c)
+                            u32 portid, u32 seq, struct mfc6_cache *c)
 {
        struct nlmsghdr *nlh;
        struct rtmsg *rtm;
 
-       nlh = nlmsg_put(skb, pid, seq, RTM_NEWROUTE, sizeof(*rtm), NLM_F_MULTI);
+       nlh = nlmsg_put(skb, portid, seq, RTM_NEWROUTE, sizeof(*rtm), NLM_F_MULTI);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -2260,7 +2260,7 @@ static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
                                if (e < s_e)
                                        goto next_entry;
                                if (ip6mr_fill_mroute(mrt, skb,
-                                                     NETLINK_CB(cb->skb).pid,
+                                                     NETLINK_CB(cb->skb).portid,
                                                      cb->nlh->nlmsg_seq,
                                                      mfc) < 0)
                                        goto done;
index 81a2d1c3da8e88f5bf10ba77506b2cdc0014217b..abfe75a2e3167887531e5febe5f621ed03e37733 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/netfilter_ipv6.h>
 #include <net/secure_seq.h>
 #include <net/checksum.h>
+#include <net/ip6_checksum.h>
 #include <net/ip6_route.h>
 #include <net/ipv6.h>
 
index 0ddf2d132e7f0840bcf327d4d0149fe2136fe943..399613b7972fdd893056ef31d5cacb635ab83f20 100644 (file)
@@ -451,10 +451,9 @@ static void rt6_probe(struct rt6_info *rt)
         * Router Reachability Probe MUST be rate-limited
         * to no more than one per minute.
         */
-       rcu_read_lock();
        neigh = rt ? rt->n : NULL;
        if (!neigh || (neigh->nud_state & NUD_VALID))
-               goto out;
+               return;
        read_lock_bh(&neigh->lock);
        if (!(neigh->nud_state & NUD_VALID) &&
            time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) {
@@ -470,8 +469,6 @@ static void rt6_probe(struct rt6_info *rt)
        } else {
                read_unlock_bh(&neigh->lock);
        }
-out:
-       rcu_read_unlock();
 }
 #else
 static inline void rt6_probe(struct rt6_info *rt)
@@ -498,7 +495,6 @@ static inline int rt6_check_neigh(struct rt6_info *rt)
        struct neighbour *neigh;
        int m;
 
-       rcu_read_lock();
        neigh = rt->n;
        if (rt->rt6i_flags & RTF_NONEXTHOP ||
            !(rt->rt6i_flags & RTF_GATEWAY))
@@ -516,7 +512,6 @@ static inline int rt6_check_neigh(struct rt6_info *rt)
                read_unlock_bh(&neigh->lock);
        } else
                m = 0;
-       rcu_read_unlock();
        return m;
 }
 
@@ -1463,8 +1458,21 @@ int ip6_route_add(struct fib6_config *cfg)
                }
                rt->dst.output = ip6_pkt_discard_out;
                rt->dst.input = ip6_pkt_discard;
-               rt->dst.error = -ENETUNREACH;
                rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP;
+               switch (cfg->fc_type) {
+               case RTN_BLACKHOLE:
+                       rt->dst.error = -EINVAL;
+                       break;
+               case RTN_PROHIBIT:
+                       rt->dst.error = -EACCES;
+                       break;
+               case RTN_THROW:
+                       rt->dst.error = -EAGAIN;
+                       break;
+               default:
+                       rt->dst.error = -ENETUNREACH;
+                       break;
+               }
                goto install_route;
        }
 
@@ -1861,7 +1869,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net,
                .fc_dst_len     = prefixlen,
                .fc_flags       = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
                                  RTF_UP | RTF_PREF(pref),
-               .fc_nlinfo.pid = 0,
+               .fc_nlinfo.portid = 0,
                .fc_nlinfo.nlh = NULL,
                .fc_nlinfo.nl_net = net,
        };
@@ -1911,7 +1919,7 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr,
                .fc_ifindex     = dev->ifindex,
                .fc_flags       = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
                                  RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
-               .fc_nlinfo.pid = 0,
+               .fc_nlinfo.portid = 0,
                .fc_nlinfo.nlh = NULL,
                .fc_nlinfo.nl_net = dev_net(dev),
        };
@@ -2261,14 +2269,18 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
        cfg->fc_src_len = rtm->rtm_src_len;
        cfg->fc_flags = RTF_UP;
        cfg->fc_protocol = rtm->rtm_protocol;
+       cfg->fc_type = rtm->rtm_type;
 
-       if (rtm->rtm_type == RTN_UNREACHABLE)
+       if (rtm->rtm_type == RTN_UNREACHABLE ||
+           rtm->rtm_type == RTN_BLACKHOLE ||
+           rtm->rtm_type == RTN_PROHIBIT ||
+           rtm->rtm_type == RTN_THROW)
                cfg->fc_flags |= RTF_REJECT;
 
        if (rtm->rtm_type == RTN_LOCAL)
                cfg->fc_flags |= RTF_LOCAL;
 
-       cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
+       cfg->fc_nlinfo.portid = NETLINK_CB(skb).portid;
        cfg->fc_nlinfo.nlh = nlh;
        cfg->fc_nlinfo.nl_net = sock_net(skb->sk);
 
@@ -2359,7 +2371,7 @@ static inline size_t rt6_nlmsg_size(void)
 static int rt6_fill_node(struct net *net,
                         struct sk_buff *skb, struct rt6_info *rt,
                         struct in6_addr *dst, struct in6_addr *src,
-                        int iif, int type, u32 pid, u32 seq,
+                        int iif, int type, u32 portid, u32 seq,
                         int prefix, int nowait, unsigned int flags)
 {
        struct rtmsg *rtm;
@@ -2375,7 +2387,7 @@ static int rt6_fill_node(struct net *net,
                }
        }
 
-       nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags);
+       nlh = nlmsg_put(skb, portid, seq, type, sizeof(*rtm), flags);
        if (!nlh)
                return -EMSGSIZE;
 
@@ -2391,8 +2403,22 @@ static int rt6_fill_node(struct net *net,
        rtm->rtm_table = table;
        if (nla_put_u32(skb, RTA_TABLE, table))
                goto nla_put_failure;
-       if (rt->rt6i_flags & RTF_REJECT)
-               rtm->rtm_type = RTN_UNREACHABLE;
+       if (rt->rt6i_flags & RTF_REJECT) {
+               switch (rt->dst.error) {
+               case -EINVAL:
+                       rtm->rtm_type = RTN_BLACKHOLE;
+                       break;
+               case -EACCES:
+                       rtm->rtm_type = RTN_PROHIBIT;
+                       break;
+               case -EAGAIN:
+                       rtm->rtm_type = RTN_THROW;
+                       break;
+               default:
+                       rtm->rtm_type = RTN_UNREACHABLE;
+                       break;
+               }
+       }
        else if (rt->rt6i_flags & RTF_LOCAL)
                rtm->rtm_type = RTN_LOCAL;
        else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK))
@@ -2465,15 +2491,11 @@ static int rt6_fill_node(struct net *net,
        if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
                goto nla_put_failure;
 
-       rcu_read_lock();
        n = rt->n;
        if (n) {
-               if (nla_put(skb, RTA_GATEWAY, 16, &n->primary_key) < 0) {
-                       rcu_read_unlock();
+               if (nla_put(skb, RTA_GATEWAY, 16, &n->primary_key) < 0)
                        goto nla_put_failure;
-               }
        }
-       rcu_read_unlock();
 
        if (rt->dst.dev &&
            nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex))
@@ -2506,7 +2528,7 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
 
        return rt6_fill_node(arg->net,
                     arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
-                    NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq,
+                    NETLINK_CB(arg->cb->skb).portid, arg->cb->nlh->nlmsg_seq,
                     prefix, 0, NLM_F_MULTI);
 }
 
@@ -2586,14 +2608,14 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
        skb_dst_set(skb, &rt->dst);
 
        err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif,
-                           RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
+                           RTM_NEWROUTE, NETLINK_CB(in_skb).portid,
                            nlh->nlmsg_seq, 0, 0, 0);
        if (err < 0) {
                kfree_skb(skb);
                goto errout;
        }
 
-       err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
+       err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
 errout:
        return err;
 }
@@ -2613,14 +2635,14 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
                goto errout;
 
        err = rt6_fill_node(net, skb, rt, NULL, NULL, 0,
-                               event, info->pid, seq, 0, 0, 0);
+                               event, info->portid, seq, 0, 0, 0);
        if (err < 0) {
                /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
                WARN_ON(err == -EMSGSIZE);
                kfree_skb(skb);
                goto errout;
        }
-       rtnl_notify(skb, net, info->pid, RTNLGRP_IPV6_ROUTE,
+       rtnl_notify(skb, net, info->portid, RTNLGRP_IPV6_ROUTE,
                    info->nlh, gfp_any());
        return;
 errout:
@@ -2675,14 +2697,12 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
 #else
        seq_puts(m, "00000000000000000000000000000000 00 ");
 #endif
-       rcu_read_lock();
        n = rt->n;
        if (n) {
                seq_printf(m, "%pi6", n->primary_key);
        } else {
                seq_puts(m, "00000000000000000000000000000000");
        }
-       rcu_read_unlock();
        seq_printf(m, " %08x %08x %08x %08x %8s\n",
                   rt->rt6i_metric, atomic_read(&rt->dst.__refcnt),
                   rt->dst.__use, rt->rt6i_flags,
index 6c7c4b92e4f8ec0e5a2aad62b33a6ada0d813c0e..c32971269280116543c0bf560e1bbc3248df034d 100644 (file)
@@ -100,7 +100,7 @@ static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info)
                goto err_out;
        }
 
-       hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
+       hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
                          &irda_nl_family, 0,  IRDA_NL_CMD_GET_MODE);
        if (hdr == NULL) {
                ret = -EMSGSIZE;
index 334f93b8cfcbf1bbc80f7cf38b039166b1357934..2ca7d7f6861c0ef8ff7613378475d9323cc97226 100644 (file)
@@ -54,7 +54,7 @@ struct pfkey_sock {
 
        struct {
                uint8_t         msg_version;
-               uint32_t        msg_pid;
+               uint32_t        msg_portid;
                int             (*dump)(struct pfkey_sock *sk);
                void            (*done)(struct pfkey_sock *sk);
                union {
@@ -1447,7 +1447,7 @@ static int key_notify_sa(struct xfrm_state *x, const struct km_event *c)
        hdr->sadb_msg_errno = 0;
        hdr->sadb_msg_reserved = 0;
        hdr->sadb_msg_seq = c->seq;
-       hdr->sadb_msg_pid = c->pid;
+       hdr->sadb_msg_pid = c->portid;
 
        pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xs_net(x));
 
@@ -1486,7 +1486,7 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, const struct sadb_msg
        else
                c.event = XFRM_MSG_UPDSA;
        c.seq = hdr->sadb_msg_seq;
-       c.pid = hdr->sadb_msg_pid;
+       c.portid = hdr->sadb_msg_pid;
        km_state_notify(x, &c);
 out:
        xfrm_state_put(x);
@@ -1523,7 +1523,7 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, const struct sadb_
                goto out;
 
        c.seq = hdr->sadb_msg_seq;
-       c.pid = hdr->sadb_msg_pid;
+       c.portid = hdr->sadb_msg_pid;
        c.event = XFRM_MSG_DELSA;
        km_state_notify(x, &c);
 out:
@@ -1701,7 +1701,7 @@ static int key_notify_sa_flush(const struct km_event *c)
        hdr->sadb_msg_satype = pfkey_proto2satype(c->data.proto);
        hdr->sadb_msg_type = SADB_FLUSH;
        hdr->sadb_msg_seq = c->seq;
-       hdr->sadb_msg_pid = c->pid;
+       hdr->sadb_msg_pid = c->portid;
        hdr->sadb_msg_version = PF_KEY_V2;
        hdr->sadb_msg_errno = (uint8_t) 0;
        hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
@@ -1736,7 +1736,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, const struct sadb_m
 
        c.data.proto = proto;
        c.seq = hdr->sadb_msg_seq;
-       c.pid = hdr->sadb_msg_pid;
+       c.portid = hdr->sadb_msg_pid;
        c.event = XFRM_MSG_FLUSHSA;
        c.net = net;
        km_state_notify(NULL, &c);
@@ -1764,7 +1764,7 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr)
        out_hdr->sadb_msg_errno = 0;
        out_hdr->sadb_msg_reserved = 0;
        out_hdr->sadb_msg_seq = count + 1;
-       out_hdr->sadb_msg_pid = pfk->dump.msg_pid;
+       out_hdr->sadb_msg_pid = pfk->dump.msg_portid;
 
        if (pfk->dump.skb)
                pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
@@ -1798,7 +1798,7 @@ static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_ms
                return -EINVAL;
 
        pfk->dump.msg_version = hdr->sadb_msg_version;
-       pfk->dump.msg_pid = hdr->sadb_msg_pid;
+       pfk->dump.msg_portid = hdr->sadb_msg_pid;
        pfk->dump.dump = pfkey_dump_sa;
        pfk->dump.done = pfkey_dump_sa_done;
        xfrm_state_walk_init(&pfk->dump.u.state, proto);
@@ -2157,7 +2157,7 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, const struct km_ev
                out_hdr->sadb_msg_type = event2poltype(c->event);
        out_hdr->sadb_msg_errno = 0;
        out_hdr->sadb_msg_seq = c->seq;
-       out_hdr->sadb_msg_pid = c->pid;
+       out_hdr->sadb_msg_pid = c->portid;
        pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp));
        return 0;
 
@@ -2272,7 +2272,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, const struct sadb_
                c.event = XFRM_MSG_NEWPOLICY;
 
        c.seq = hdr->sadb_msg_seq;
-       c.pid = hdr->sadb_msg_pid;
+       c.portid = hdr->sadb_msg_pid;
 
        km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
        xfrm_pol_put(xp);
@@ -2351,7 +2351,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa
                goto out;
 
        c.seq = hdr->sadb_msg_seq;
-       c.pid = hdr->sadb_msg_pid;
+       c.portid = hdr->sadb_msg_pid;
        c.data.byid = 0;
        c.event = XFRM_MSG_DELPOLICY;
        km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
@@ -2597,7 +2597,7 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, const struct sadb_
                if (err)
                        goto out;
                c.seq = hdr->sadb_msg_seq;
-               c.pid = hdr->sadb_msg_pid;
+               c.portid = hdr->sadb_msg_pid;
                c.data.byid = 1;
                c.event = XFRM_MSG_DELPOLICY;
                km_policy_notify(xp, dir, &c);
@@ -2634,7 +2634,7 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr)
        out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC;
        out_hdr->sadb_msg_errno = 0;
        out_hdr->sadb_msg_seq = count + 1;
-       out_hdr->sadb_msg_pid = pfk->dump.msg_pid;
+       out_hdr->sadb_msg_pid = pfk->dump.msg_portid;
 
        if (pfk->dump.skb)
                pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
@@ -2663,7 +2663,7 @@ static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, const struct sadb
                return -EBUSY;
 
        pfk->dump.msg_version = hdr->sadb_msg_version;
-       pfk->dump.msg_pid = hdr->sadb_msg_pid;
+       pfk->dump.msg_portid = hdr->sadb_msg_pid;
        pfk->dump.dump = pfkey_dump_sp;
        pfk->dump.done = pfkey_dump_sp_done;
        xfrm_policy_walk_init(&pfk->dump.u.policy, XFRM_POLICY_TYPE_MAIN);
@@ -2682,7 +2682,7 @@ static int key_notify_policy_flush(const struct km_event *c)
        hdr = (struct sadb_msg *) skb_put(skb_out, sizeof(struct sadb_msg));
        hdr->sadb_msg_type = SADB_X_SPDFLUSH;
        hdr->sadb_msg_seq = c->seq;
-       hdr->sadb_msg_pid = c->pid;
+       hdr->sadb_msg_pid = c->portid;
        hdr->sadb_msg_version = PF_KEY_V2;
        hdr->sadb_msg_errno = (uint8_t) 0;
        hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
@@ -2711,7 +2711,7 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, const struct sad
 
        c.data.type = XFRM_POLICY_TYPE_MAIN;
        c.event = XFRM_MSG_FLUSHPOLICY;
-       c.pid = hdr->sadb_msg_pid;
+       c.portid = hdr->sadb_msg_pid;
        c.seq = hdr->sadb_msg_seq;
        c.net = net;
        km_policy_notify(NULL, 0, &c);
index f9ee74deeac26f5469271a0800669cc82ffddc63..ba89997bcd2e68d2b2ac414ec8fb137fd9357467 100644 (file)
@@ -67,6 +67,7 @@ static inline struct l2tp_eth_net *l2tp_eth_pernet(struct net *net)
        return net_generic(net, l2tp_eth_net_id);
 }
 
+static struct lock_class_key l2tp_eth_tx_busylock;
 static int l2tp_eth_dev_init(struct net_device *dev)
 {
        struct l2tp_eth *priv = netdev_priv(dev);
@@ -74,7 +75,7 @@ static int l2tp_eth_dev_init(struct net_device *dev)
        priv->dev = dev;
        eth_hw_addr_random(dev);
        memset(&dev->broadcast[0], 0xff, 6);
-
+       dev->qdisc_tx_busylock = &l2tp_eth_tx_busylock;
        return 0;
 }
 
index d71cd9229a47a8fd85efbf3f5430c66a3e3ad5cd..6ec3f67ad3f191910ff0a3485d7b7c35bf84f803 100644 (file)
@@ -78,7 +78,7 @@ static int l2tp_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
                goto out;
        }
 
-       hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
+       hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
                          &l2tp_nl_family, 0, L2TP_CMD_NOOP);
        if (IS_ERR(hdr)) {
                ret = PTR_ERR(hdr);
@@ -87,7 +87,7 @@ static int l2tp_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
 
        genlmsg_end(msg, hdr);
 
-       return genlmsg_unicast(genl_info_net(info), msg, info->snd_pid);
+       return genlmsg_unicast(genl_info_net(info), msg, info->snd_portid);
 
 err_out:
        nlmsg_free(msg);
@@ -235,7 +235,7 @@ out:
        return ret;
 }
 
-static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 pid, u32 seq, int flags,
+static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 portid, u32 seq, int flags,
                               struct l2tp_tunnel *tunnel)
 {
        void *hdr;
@@ -248,7 +248,7 @@ static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 pid, u32 seq, int flags,
        struct l2tp_stats stats;
        unsigned int start;
 
-       hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags,
+       hdr = genlmsg_put(skb, portid, seq, &l2tp_nl_family, flags,
                          L2TP_CMD_TUNNEL_GET);
        if (IS_ERR(hdr))
                return PTR_ERR(hdr);
@@ -359,12 +359,12 @@ static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info)
                goto out;
        }
 
-       ret = l2tp_nl_tunnel_send(msg, info->snd_pid, info->snd_seq,
+       ret = l2tp_nl_tunnel_send(msg, info->snd_portid, info->snd_seq,
                                  NLM_F_ACK, tunnel);
        if (ret < 0)
                goto err_out;
 
-       return genlmsg_unicast(net, msg, info->snd_pid);
+       return genlmsg_unicast(net, msg, info->snd_portid);
 
 err_out:
        nlmsg_free(msg);
@@ -384,7 +384,7 @@ static int l2tp_nl_cmd_tunnel_dump(struct sk_buff *skb, struct netlink_callback
                if (tunnel == NULL)
                        goto out;
 
-               if (l2tp_nl_tunnel_send(skb, NETLINK_CB(cb->skb).pid,
+               if (l2tp_nl_tunnel_send(skb, NETLINK_CB(cb->skb).portid,
                                        cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                        tunnel) <= 0)
                        goto out;
@@ -604,7 +604,7 @@ out:
        return ret;
 }
 
-static int l2tp_nl_session_send(struct sk_buff *skb, u32 pid, u32 seq, int flags,
+static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int flags,
                                struct l2tp_session *session)
 {
        void *hdr;
@@ -616,7 +616,7 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 pid, u32 seq, int flags
 
        sk = tunnel->sock;
 
-       hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags, L2TP_CMD_SESSION_GET);
+       hdr = genlmsg_put(skb, portid, seq, &l2tp_nl_family, flags, L2TP_CMD_SESSION_GET);
        if (IS_ERR(hdr))
                return PTR_ERR(hdr);
 
@@ -705,12 +705,12 @@ static int l2tp_nl_cmd_session_get(struct sk_buff *skb, struct genl_info *info)
                goto out;
        }
 
-       ret = l2tp_nl_session_send(msg, info->snd_pid, info->snd_seq,
+       ret = l2tp_nl_session_send(msg, info->snd_portid, info->snd_seq,
                                   0, session);
        if (ret < 0)
                goto err_out;
 
-       return genlmsg_unicast(genl_info_net(info), msg, info->snd_pid);
+       return genlmsg_unicast(genl_info_net(info), msg, info->snd_portid);
 
 err_out:
        nlmsg_free(msg);
@@ -742,7 +742,7 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback
                        continue;
                }
 
-               if (l2tp_nl_session_send(skb, NETLINK_CB(cb->skb).pid,
+               if (l2tp_nl_session_send(skb, NETLINK_CB(cb->skb).portid,
                                         cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                         session) <= 0)
                        break;
index 9730882697aaedbab0beee66f0f12a654b97b63a..ad39ef406851a1ac373f22dd152d789419cd5258 100644 (file)
@@ -563,13 +563,13 @@ flag_exist(const struct nlmsghdr *nlh)
 }
 
 static struct nlmsghdr *
-start_msg(struct sk_buff *skb, u32 pid, u32 seq, unsigned int flags,
+start_msg(struct sk_buff *skb, u32 portid, u32 seq, unsigned int flags,
          enum ipset_cmd cmd)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
 
-       nlh = nlmsg_put(skb, pid, seq, cmd | (NFNL_SUBSYS_IPSET << 8),
+       nlh = nlmsg_put(skb, portid, seq, cmd | (NFNL_SUBSYS_IPSET << 8),
                        sizeof(*nfmsg), flags);
        if (nlh == NULL)
                return NULL;
@@ -1045,7 +1045,7 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
        ip_set_id_t index = IPSET_INVALID_ID, max;
        struct ip_set *set = NULL;
        struct nlmsghdr *nlh = NULL;
-       unsigned int flags = NETLINK_CB(cb->skb).pid ? NLM_F_MULTI : 0;
+       unsigned int flags = NETLINK_CB(cb->skb).portid ? NLM_F_MULTI : 0;
        u32 dump_type, dump_flags;
        int ret = 0;
 
@@ -1093,7 +1093,7 @@ dump_last:
                        pr_debug("reference set\n");
                        __ip_set_get(index);
                }
-               nlh = start_msg(skb, NETLINK_CB(cb->skb).pid,
+               nlh = start_msg(skb, NETLINK_CB(cb->skb).portid,
                                cb->nlh->nlmsg_seq, flags,
                                IPSET_CMD_LIST);
                if (!nlh) {
@@ -1226,7 +1226,7 @@ call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set,
                skb2 = nlmsg_new(payload, GFP_KERNEL);
                if (skb2 == NULL)
                        return -ENOMEM;
-               rep = __nlmsg_put(skb2, NETLINK_CB(skb).pid,
+               rep = __nlmsg_put(skb2, NETLINK_CB(skb).portid,
                                  nlh->nlmsg_seq, NLMSG_ERROR, payload, 0);
                errmsg = nlmsg_data(rep);
                errmsg->error = ret;
@@ -1241,7 +1241,7 @@ call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set,
 
                *errline = lineno;
 
-               netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+               netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
                /* Signal netlink not to send its ACK/errmsg.  */
                return -EINTR;
        }
@@ -1416,7 +1416,7 @@ ip_set_header(struct sock *ctnl, struct sk_buff *skb,
        if (skb2 == NULL)
                return -ENOMEM;
 
-       nlh2 = start_msg(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0,
+       nlh2 = start_msg(skb2, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0,
                         IPSET_CMD_HEADER);
        if (!nlh2)
                goto nlmsg_failure;
@@ -1428,7 +1428,7 @@ ip_set_header(struct sock *ctnl, struct sk_buff *skb,
                goto nla_put_failure;
        nlmsg_end(skb2, nlh2);
 
-       ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+       ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
        if (ret < 0)
                return ret;
 
@@ -1476,7 +1476,7 @@ ip_set_type(struct sock *ctnl, struct sk_buff *skb,
        if (skb2 == NULL)
                return -ENOMEM;
 
-       nlh2 = start_msg(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0,
+       nlh2 = start_msg(skb2, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0,
                         IPSET_CMD_TYPE);
        if (!nlh2)
                goto nlmsg_failure;
@@ -1489,7 +1489,7 @@ ip_set_type(struct sock *ctnl, struct sk_buff *skb,
        nlmsg_end(skb2, nlh2);
 
        pr_debug("Send TYPE, nlmsg_len: %u\n", nlh2->nlmsg_len);
-       ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+       ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
        if (ret < 0)
                return ret;
 
@@ -1525,7 +1525,7 @@ ip_set_protocol(struct sock *ctnl, struct sk_buff *skb,
        if (skb2 == NULL)
                return -ENOMEM;
 
-       nlh2 = start_msg(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0,
+       nlh2 = start_msg(skb2, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0,
                         IPSET_CMD_PROTOCOL);
        if (!nlh2)
                goto nlmsg_failure;
@@ -1533,7 +1533,7 @@ ip_set_protocol(struct sock *ctnl, struct sk_buff *skb,
                goto nla_put_failure;
        nlmsg_end(skb2, nlh2);
 
-       ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+       ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
        if (ret < 0)
                return ret;
 
index 37b38d0791cd0b7557a740f65aa9ce0774ae501c..7e7198b51c068a7ea10446af4d390a9e6e2044f4 100644 (file)
@@ -2938,7 +2938,7 @@ static int ip_vs_genl_dump_service(struct sk_buff *skb,
 {
        void *hdr;
 
-       hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
+       hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
                          &ip_vs_genl_family, NLM_F_MULTI,
                          IPVS_CMD_NEW_SERVICE);
        if (!hdr)
@@ -3127,7 +3127,7 @@ static int ip_vs_genl_dump_dest(struct sk_buff *skb, struct ip_vs_dest *dest,
 {
        void *hdr;
 
-       hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
+       hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
                          &ip_vs_genl_family, NLM_F_MULTI,
                          IPVS_CMD_NEW_DEST);
        if (!hdr)
@@ -3256,7 +3256,7 @@ static int ip_vs_genl_dump_daemon(struct sk_buff *skb, __be32 state,
                                  struct netlink_callback *cb)
 {
        void *hdr;
-       hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
+       hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
                          &ip_vs_genl_family, NLM_F_MULTI,
                          IPVS_CMD_NEW_DAEMON);
        if (!hdr)
index e7be79e640de0397ac9f5e5aaab00faf1f2c8730..de9781b6464f0940d391555489782bf63f1c956e 100644 (file)
@@ -61,7 +61,7 @@ void nf_ct_deliver_cached_events(struct nf_conn *ct)
                goto out_unlock;
 
        item.ct = ct;
-       item.pid = 0;
+       item.portid = 0;
        item.report = 0;
 
        ret = notify->fcn(events | missed, &item);
index 090d267ee605c5de567f6c8d847e81bf36dc28cd..2dcd080b8c4f9eebdc65b410adc8be3845915c69 100644 (file)
@@ -418,16 +418,16 @@ nla_put_failure:
 }
 
 static int
-ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
+ctnetlink_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
                    struct nf_conn *ct)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
        struct nlattr *nest_parms;
-       unsigned int flags = pid ? NLM_F_MULTI : 0, event;
+       unsigned int flags = portid ? NLM_F_MULTI : 0, event;
 
        event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_NEW);
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -604,7 +604,7 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
                goto errout;
 
        type |= NFNL_SUBSYS_CTNETLINK << 8;
-       nlh = nlmsg_put(skb, item->pid, 0, type, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, item->portid, 0, type, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -680,7 +680,7 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
        rcu_read_unlock();
 
        nlmsg_end(skb, nlh);
-       err = nfnetlink_send(skb, net, item->pid, group, item->report,
+       err = nfnetlink_send(skb, net, item->portid, group, item->report,
                             GFP_ATOMIC);
        if (err == -ENOBUFS || err == -EAGAIN)
                return -ENOBUFS;
@@ -757,7 +757,7 @@ restart:
 #endif
                        rcu_read_lock();
                        res =
-                       ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
+                       ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).portid,
                                            cb->nlh->nlmsg_seq,
                                            NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
                                            ct);
@@ -961,7 +961,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
        else {
                /* Flush the whole table */
                nf_conntrack_flush_report(net,
-                                        NETLINK_CB(skb).pid,
+                                        NETLINK_CB(skb).portid,
                                         nlmsg_report(nlh));
                return 0;
        }
@@ -985,7 +985,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
 
        if (del_timer(&ct->timeout)) {
                if (nf_conntrack_event_report(IPCT_DESTROY, ct,
-                                             NETLINK_CB(skb).pid,
+                                             NETLINK_CB(skb).portid,
                                              nlmsg_report(nlh)) < 0) {
                        nf_ct_delete_from_lists(ct);
                        /* we failed to report the event, try later */
@@ -1069,14 +1069,14 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
        }
 
        rcu_read_lock();
-       err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq,
+       err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
                                  NFNL_MSG_TYPE(nlh->nlmsg_type), ct);
        rcu_read_unlock();
        nf_ct_put(ct);
        if (err <= 0)
                goto free;
 
-       err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+       err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
        if (err < 0)
                goto out;
 
@@ -1613,7 +1613,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
                                                      (1 << IPCT_PROTOINFO) |
                                                      (1 << IPCT_NATSEQADJ) |
                                                      (1 << IPCT_MARK) | events,
-                                                     ct, NETLINK_CB(skb).pid,
+                                                     ct, NETLINK_CB(skb).portid,
                                                      nlmsg_report(nlh));
                        nf_ct_put(ct);
                }
@@ -1635,7 +1635,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
                                                      (1 << IPCT_PROTOINFO) |
                                                      (1 << IPCT_NATSEQADJ) |
                                                      (1 << IPCT_MARK),
-                                                     ct, NETLINK_CB(skb).pid,
+                                                     ct, NETLINK_CB(skb).portid,
                                                      nlmsg_report(nlh));
                }
        }
@@ -1645,15 +1645,15 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
 }
 
 static int
-ctnetlink_ct_stat_cpu_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
+ctnetlink_ct_stat_cpu_fill_info(struct sk_buff *skb, u32 portid, u32 seq,
                                __u16 cpu, const struct ip_conntrack_stat *st)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       unsigned int flags = pid ? NLM_F_MULTI : 0, event;
+       unsigned int flags = portid ? NLM_F_MULTI : 0, event;
 
        event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_GET_STATS_CPU);
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -1705,7 +1705,7 @@ ctnetlink_ct_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb)
 
                st = per_cpu_ptr(net->ct.stat, cpu);
                if (ctnetlink_ct_stat_cpu_fill_info(skb,
-                                                   NETLINK_CB(cb->skb).pid,
+                                                   NETLINK_CB(cb->skb).portid,
                                                    cb->nlh->nlmsg_seq,
                                                    cpu, st) < 0)
                                break;
@@ -1731,16 +1731,16 @@ ctnetlink_stat_ct_cpu(struct sock *ctnl, struct sk_buff *skb,
 }
 
 static int
-ctnetlink_stat_ct_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
+ctnetlink_stat_ct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
                            struct net *net)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       unsigned int flags = pid ? NLM_F_MULTI : 0, event;
+       unsigned int flags = portid ? NLM_F_MULTI : 0, event;
        unsigned int nr_conntracks = atomic_read(&net->ct.count);
 
        event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_GET_STATS);
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -1773,14 +1773,14 @@ ctnetlink_stat_ct(struct sock *ctnl, struct sk_buff *skb,
        if (skb2 == NULL)
                return -ENOMEM;
 
-       err = ctnetlink_stat_ct_fill_info(skb2, NETLINK_CB(skb).pid,
+       err = ctnetlink_stat_ct_fill_info(skb2, NETLINK_CB(skb).portid,
                                          nlh->nlmsg_seq,
                                          NFNL_MSG_TYPE(nlh->nlmsg_type),
                                          sock_net(skb->sk));
        if (err <= 0)
                goto free;
 
-       err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+       err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
        if (err < 0)
                goto out;
 
@@ -2070,15 +2070,15 @@ nla_put_failure:
 }
 
 static int
-ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
+ctnetlink_exp_fill_info(struct sk_buff *skb, u32 portid, u32 seq,
                        int event, const struct nf_conntrack_expect *exp)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       unsigned int flags = pid ? NLM_F_MULTI : 0;
+       unsigned int flags = portid ? NLM_F_MULTI : 0;
 
        event |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -2129,7 +2129,7 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
                goto errout;
 
        type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
-       nlh = nlmsg_put(skb, item->pid, 0, type, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, item->portid, 0, type, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -2144,7 +2144,7 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
        rcu_read_unlock();
 
        nlmsg_end(skb, nlh);
-       nfnetlink_send(skb, net, item->pid, group, item->report, GFP_ATOMIC);
+       nfnetlink_send(skb, net, item->portid, group, item->report, GFP_ATOMIC);
        return 0;
 
 nla_put_failure:
@@ -2187,7 +2187,7 @@ restart:
                                cb->args[1] = 0;
                        }
                        if (ctnetlink_exp_fill_info(skb,
-                                                   NETLINK_CB(cb->skb).pid,
+                                                   NETLINK_CB(cb->skb).portid,
                                                    cb->nlh->nlmsg_seq,
                                                    IPCTNL_MSG_EXP_NEW,
                                                    exp) < 0) {
@@ -2280,14 +2280,14 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
        }
 
        rcu_read_lock();
-       err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid,
+       err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).portid,
                                      nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, exp);
        rcu_read_unlock();
        nf_ct_expect_put(exp);
        if (err <= 0)
                goto free;
 
-       err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+       err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
        if (err < 0)
                goto out;
 
@@ -2341,7 +2341,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                /* after list removal, usage count == 1 */
                spin_lock_bh(&nf_conntrack_lock);
                if (del_timer(&exp->timeout)) {
-                       nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).pid,
+                       nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).portid,
                                                   nlmsg_report(nlh));
                        nf_ct_expect_put(exp);
                }
@@ -2363,7 +2363,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                                if (!strcmp(m_help->helper->name, name) &&
                                    del_timer(&exp->timeout)) {
                                        nf_ct_unlink_expect_report(exp,
-                                                       NETLINK_CB(skb).pid,
+                                                       NETLINK_CB(skb).portid,
                                                        nlmsg_report(nlh));
                                        nf_ct_expect_put(exp);
                                }
@@ -2379,7 +2379,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                                                  hnode) {
                                if (del_timer(&exp->timeout)) {
                                        nf_ct_unlink_expect_report(exp,
-                                                       NETLINK_CB(skb).pid,
+                                                       NETLINK_CB(skb).portid,
                                                        nlmsg_report(nlh));
                                        nf_ct_expect_put(exp);
                                }
@@ -2444,7 +2444,7 @@ static int
 ctnetlink_create_expect(struct net *net, u16 zone,
                        const struct nlattr * const cda[],
                        u_int8_t u3,
-                       u32 pid, int report)
+                       u32 portid, int report)
 {
        struct nf_conntrack_tuple tuple, mask, master_tuple;
        struct nf_conntrack_tuple_hash *h = NULL;
@@ -2557,7 +2557,7 @@ ctnetlink_create_expect(struct net *net, u16 zone,
                if (err < 0)
                        goto err_out;
        }
-       err = nf_ct_expect_related_report(exp, pid, report);
+       err = nf_ct_expect_related_report(exp, portid, report);
 err_out:
        nf_ct_expect_put(exp);
 out:
@@ -2600,7 +2600,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
                if (nlh->nlmsg_flags & NLM_F_CREATE) {
                        err = ctnetlink_create_expect(net, zone, cda,
                                                      u3,
-                                                     NETLINK_CB(skb).pid,
+                                                     NETLINK_CB(skb).portid,
                                                      nlmsg_report(nlh));
                }
                return err;
@@ -2615,15 +2615,15 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
 }
 
 static int
-ctnetlink_exp_stat_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int cpu,
+ctnetlink_exp_stat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, int cpu,
                             const struct ip_conntrack_stat *st)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       unsigned int flags = pid ? NLM_F_MULTI : 0, event;
+       unsigned int flags = portid ? NLM_F_MULTI : 0, event;
 
        event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_EXP_GET_STATS_CPU);
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -2662,7 +2662,7 @@ ctnetlink_exp_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb)
                        continue;
 
                st = per_cpu_ptr(net->ct.stat, cpu);
-               if (ctnetlink_exp_stat_fill_info(skb, NETLINK_CB(cb->skb).pid,
+               if (ctnetlink_exp_stat_fill_info(skb, NETLINK_CB(cb->skb).portid,
                                                 cb->nlh->nlmsg_seq,
                                                 cpu, st) < 0)
                        break;
index a26503342e7184737c419ddd36144dacebc59d20..ffb92c03a358a8ce64c9e824a09db72a823b76d8 100644 (file)
@@ -241,7 +241,7 @@ static int __net_init nfnetlink_net_init(struct net *net)
 #endif
        };
 
-       nfnl = netlink_kernel_create(net, NETLINK_NETFILTER, THIS_MODULE, &cfg);
+       nfnl = netlink_kernel_create(net, NETLINK_NETFILTER, &cfg);
        if (!nfnl)
                return -ENOMEM;
        net->nfnl_stash = nfnl;
index d7ec928790717ef6d1f81d26a0e65279615806eb..589d686f0b4cbe0f25b785790dfeba9bf1a13d98 100644 (file)
@@ -91,16 +91,16 @@ nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb,
 }
 
 static int
-nfnl_acct_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
+nfnl_acct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
                   int event, struct nf_acct *acct)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       unsigned int flags = pid ? NLM_F_MULTI : 0;
+       unsigned int flags = portid ? NLM_F_MULTI : 0;
        u64 pkts, bytes;
 
        event |= NFNL_SUBSYS_ACCT << 8;
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -150,7 +150,7 @@ nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb)
                if (last && cur != last)
                        continue;
 
-               if (nfnl_acct_fill_info(skb, NETLINK_CB(cb->skb).pid,
+               if (nfnl_acct_fill_info(skb, NETLINK_CB(cb->skb).portid,
                                       cb->nlh->nlmsg_seq,
                                       NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
                                       NFNL_MSG_ACCT_NEW, cur) < 0) {
@@ -195,7 +195,7 @@ nfnl_acct_get(struct sock *nfnl, struct sk_buff *skb,
                        break;
                }
 
-               ret = nfnl_acct_fill_info(skb2, NETLINK_CB(skb).pid,
+               ret = nfnl_acct_fill_info(skb2, NETLINK_CB(skb).portid,
                                         nlh->nlmsg_seq,
                                         NFNL_MSG_TYPE(nlh->nlmsg_type),
                                         NFNL_MSG_ACCT_NEW, cur);
@@ -203,7 +203,7 @@ nfnl_acct_get(struct sock *nfnl, struct sk_buff *skb,
                        kfree_skb(skb2);
                        break;
                }
-               ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).pid,
+               ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).portid,
                                        MSG_DONTWAIT);
                if (ret > 0)
                        ret = 0;
index 32a1ba3f3e27dd9b648d918e8b72a31b7ef2a53e..3678073360a3b6dcb2ec5b7d5e9d2239ea9e636c 100644 (file)
@@ -395,16 +395,16 @@ nla_put_failure:
 }
 
 static int
-nfnl_cthelper_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
+nfnl_cthelper_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
                        int event, struct nf_conntrack_helper *helper)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       unsigned int flags = pid ? NLM_F_MULTI : 0;
+       unsigned int flags = portid ? NLM_F_MULTI : 0;
        int status;
 
        event |= NFNL_SUBSYS_CTHELPER << 8;
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -468,7 +468,7 @@ restart:
                                cb->args[1] = 0;
                        }
                        if (nfnl_cthelper_fill_info(skb,
-                                           NETLINK_CB(cb->skb).pid,
+                                           NETLINK_CB(cb->skb).portid,
                                            cb->nlh->nlmsg_seq,
                                            NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
                                            NFNL_MSG_CTHELPER_NEW, cur) < 0) {
@@ -538,7 +538,7 @@ nfnl_cthelper_get(struct sock *nfnl, struct sk_buff *skb,
                                break;
                        }
 
-                       ret = nfnl_cthelper_fill_info(skb2, NETLINK_CB(skb).pid,
+                       ret = nfnl_cthelper_fill_info(skb2, NETLINK_CB(skb).portid,
                                                nlh->nlmsg_seq,
                                                NFNL_MSG_TYPE(nlh->nlmsg_type),
                                                NFNL_MSG_CTHELPER_NEW, cur);
@@ -547,7 +547,7 @@ nfnl_cthelper_get(struct sock *nfnl, struct sk_buff *skb,
                                break;
                        }
 
-                       ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).pid,
+                       ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).portid,
                                                MSG_DONTWAIT);
                        if (ret > 0)
                                ret = 0;
index cdecbc8fe965e9ed66216e1702fd1b43fe569091..8847b4d8be06b9ad536c2bb32d9bbd3d34a7c289 100644 (file)
@@ -155,16 +155,16 @@ err_proto_put:
 }
 
 static int
-ctnl_timeout_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
+ctnl_timeout_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
                       int event, struct ctnl_timeout *timeout)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       unsigned int flags = pid ? NLM_F_MULTI : 0;
+       unsigned int flags = portid ? NLM_F_MULTI : 0;
        struct nf_conntrack_l4proto *l4proto = timeout->l4proto;
 
        event |= NFNL_SUBSYS_CTNETLINK_TIMEOUT << 8;
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
        if (nlh == NULL)
                goto nlmsg_failure;
 
@@ -222,7 +222,7 @@ ctnl_timeout_dump(struct sk_buff *skb, struct netlink_callback *cb)
                if (last && cur != last)
                        continue;
 
-               if (ctnl_timeout_fill_info(skb, NETLINK_CB(cb->skb).pid,
+               if (ctnl_timeout_fill_info(skb, NETLINK_CB(cb->skb).portid,
                                           cb->nlh->nlmsg_seq,
                                           NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
                                           IPCTNL_MSG_TIMEOUT_NEW, cur) < 0) {
@@ -268,7 +268,7 @@ cttimeout_get_timeout(struct sock *ctnl, struct sk_buff *skb,
                        break;
                }
 
-               ret = ctnl_timeout_fill_info(skb2, NETLINK_CB(skb).pid,
+               ret = ctnl_timeout_fill_info(skb2, NETLINK_CB(skb).portid,
                                             nlh->nlmsg_seq,
                                             NFNL_MSG_TYPE(nlh->nlmsg_type),
                                             IPCTNL_MSG_TIMEOUT_NEW, cur);
@@ -276,7 +276,7 @@ cttimeout_get_timeout(struct sock *ctnl, struct sk_buff *skb,
                        kfree_skb(skb2);
                        break;
                }
-               ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid,
+               ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid,
                                        MSG_DONTWAIT);
                if (ret > 0)
                        ret = 0;
index be194b144297f429b68ccd04997a33fab5971a76..8cb67c4dbd620661e34fa95a1192c67071a455ae 100644 (file)
@@ -56,7 +56,7 @@ struct nfulnl_instance {
        struct sk_buff *skb;            /* pre-allocatd skb */
        struct timer_list timer;
        struct user_namespace *peer_user_ns;    /* User namespace of the peer process */
-       int peer_pid;                   /* PID of the peer process */
+       int peer_portid;                        /* PORTID of the peer process */
 
        /* configurable parameters */
        unsigned int flushtimeout;      /* timeout until queue flush */
@@ -133,7 +133,7 @@ instance_put(struct nfulnl_instance *inst)
 static void nfulnl_timer(unsigned long data);
 
 static struct nfulnl_instance *
-instance_create(u_int16_t group_num, int pid, struct user_namespace *user_ns)
+instance_create(u_int16_t group_num, int portid, struct user_namespace *user_ns)
 {
        struct nfulnl_instance *inst;
        int err;
@@ -164,7 +164,7 @@ instance_create(u_int16_t group_num, int pid, struct user_namespace *user_ns)
        setup_timer(&inst->timer, nfulnl_timer, (unsigned long)inst);
 
        inst->peer_user_ns = user_ns;
-       inst->peer_pid = pid;
+       inst->peer_portid = portid;
        inst->group_num = group_num;
 
        inst->qthreshold        = NFULNL_QTHRESH_DEFAULT;
@@ -336,7 +336,7 @@ __nfulnl_send(struct nfulnl_instance *inst)
                if (!nlh)
                        goto out;
        }
-       status = nfnetlink_unicast(inst->skb, &init_net, inst->peer_pid,
+       status = nfnetlink_unicast(inst->skb, &init_net, inst->peer_portid,
                                   MSG_DONTWAIT);
 
        inst->qlen = 0;
@@ -703,7 +703,7 @@ nfulnl_rcv_nl_event(struct notifier_block *this,
        if (event == NETLINK_URELEASE && n->protocol == NETLINK_NETFILTER) {
                int i;
 
-               /* destroy all instances for this pid */
+               /* destroy all instances for this portid */
                spin_lock_bh(&instances_lock);
                for  (i = 0; i < INSTANCE_BUCKETS; i++) {
                        struct hlist_node *tmp, *t2;
@@ -712,7 +712,7 @@ nfulnl_rcv_nl_event(struct notifier_block *this,
 
                        hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
                                if ((net_eq(n->net, &init_net)) &&
-                                   (n->pid == inst->peer_pid))
+                                   (n->portid == inst->peer_portid))
                                        __instance_destroy(inst);
                        }
                }
@@ -774,7 +774,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
        }
 
        inst = instance_lookup_get(group_num);
-       if (inst && inst->peer_pid != NETLINK_CB(skb).pid) {
+       if (inst && inst->peer_portid != NETLINK_CB(skb).portid) {
                ret = -EPERM;
                goto out_put;
        }
@@ -788,7 +788,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
                        }
 
                        inst = instance_create(group_num,
-                                              NETLINK_CB(skb).pid,
+                                              NETLINK_CB(skb).portid,
                                               sk_user_ns(NETLINK_CB(skb).ssk));
                        if (IS_ERR(inst)) {
                                ret = PTR_ERR(inst);
@@ -947,7 +947,7 @@ static int seq_show(struct seq_file *s, void *v)
 
        return seq_printf(s, "%5d %6d %5d %1d %5d %6d %2d\n",
                          inst->group_num,
-                         inst->peer_pid, inst->qlen,
+                         inst->peer_portid, inst->qlen,
                          inst->copy_mode, inst->copy_range,
                          inst->flushtimeout, atomic_read(&inst->use));
 }
index 5c2d78d3a4d829d819c95699e90cbc3fba894851..43de3a03ee766796fca787aec67b2efa1cc3d614 100644 (file)
@@ -44,7 +44,7 @@ struct nfqnl_instance {
        struct hlist_node hlist;                /* global list of queues */
        struct rcu_head rcu;
 
-       int peer_pid;
+       int peer_portid;
        unsigned int queue_maxlen;
        unsigned int copy_range;
        unsigned int queue_dropped;
@@ -92,7 +92,7 @@ instance_lookup(u_int16_t queue_num)
 }
 
 static struct nfqnl_instance *
-instance_create(u_int16_t queue_num, int pid)
+instance_create(u_int16_t queue_num, int portid)
 {
        struct nfqnl_instance *inst;
        unsigned int h;
@@ -111,7 +111,7 @@ instance_create(u_int16_t queue_num, int pid)
        }
 
        inst->queue_num = queue_num;
-       inst->peer_pid = pid;
+       inst->peer_portid = portid;
        inst->queue_maxlen = NFQNL_QMAX_DEFAULT;
        inst->copy_range = 0xfffff;
        inst->copy_mode = NFQNL_COPY_NONE;
@@ -439,7 +439,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
        }
        spin_lock_bh(&queue->lock);
 
-       if (!queue->peer_pid) {
+       if (!queue->peer_portid) {
                err = -EINVAL;
                goto err_out_free_nskb;
        }
@@ -458,7 +458,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
        *packet_id_ptr = htonl(entry->id);
 
        /* nfnetlink_unicast will either free the nskb or add it to a socket */
-       err = nfnetlink_unicast(nskb, &init_net, queue->peer_pid, MSG_DONTWAIT);
+       err = nfnetlink_unicast(nskb, &init_net, queue->peer_portid, MSG_DONTWAIT);
        if (err < 0) {
                queue->queue_user_dropped++;
                goto err_out_unlock;
@@ -615,7 +615,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
        if (event == NETLINK_URELEASE && n->protocol == NETLINK_NETFILTER) {
                int i;
 
-               /* destroy all instances for this pid */
+               /* destroy all instances for this portid */
                spin_lock(&instances_lock);
                for (i = 0; i < INSTANCE_BUCKETS; i++) {
                        struct hlist_node *tmp, *t2;
@@ -624,7 +624,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
 
                        hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
                                if ((n->net == &init_net) &&
-                                   (n->pid == inst->peer_pid))
+                                   (n->portid == inst->peer_portid))
                                        __instance_destroy(inst);
                        }
                }
@@ -649,7 +649,7 @@ static const struct nla_policy nfqa_verdict_batch_policy[NFQA_MAX+1] = {
        [NFQA_MARK]             = { .type = NLA_U32 },
 };
 
-static struct nfqnl_instance *verdict_instance_lookup(u16 queue_num, int nlpid)
+static struct nfqnl_instance *verdict_instance_lookup(u16 queue_num, int nlportid)
 {
        struct nfqnl_instance *queue;
 
@@ -657,7 +657,7 @@ static struct nfqnl_instance *verdict_instance_lookup(u16 queue_num, int nlpid)
        if (!queue)
                return ERR_PTR(-ENODEV);
 
-       if (queue->peer_pid != nlpid)
+       if (queue->peer_portid != nlportid)
                return ERR_PTR(-EPERM);
 
        return queue;
@@ -697,7 +697,7 @@ nfqnl_recv_verdict_batch(struct sock *ctnl, struct sk_buff *skb,
        LIST_HEAD(batch_list);
        u16 queue_num = ntohs(nfmsg->res_id);
 
-       queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).pid);
+       queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).portid);
        if (IS_ERR(queue))
                return PTR_ERR(queue);
 
@@ -748,7 +748,7 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
        queue = instance_lookup(queue_num);
        if (!queue)
 
-       queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).pid);
+       queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).portid);
        if (IS_ERR(queue))
                return PTR_ERR(queue);
 
@@ -831,7 +831,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
 
        rcu_read_lock();
        queue = instance_lookup(queue_num);
-       if (queue && queue->peer_pid != NETLINK_CB(skb).pid) {
+       if (queue && queue->peer_portid != NETLINK_CB(skb).portid) {
                ret = -EPERM;
                goto err_out_unlock;
        }
@@ -843,7 +843,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
                                ret = -EBUSY;
                                goto err_out_unlock;
                        }
-                       queue = instance_create(queue_num, NETLINK_CB(skb).pid);
+                       queue = instance_create(queue_num, NETLINK_CB(skb).portid);
                        if (IS_ERR(queue)) {
                                ret = PTR_ERR(queue);
                                goto err_out_unlock;
@@ -1015,7 +1015,7 @@ static int seq_show(struct seq_file *s, void *v)
 
        return seq_printf(s, "%5d %6d %5d %1d %5d %5d %5d %8d %2d\n",
                          inst->queue_num,
-                         inst->peer_pid, inst->queue_total,
+                         inst->peer_portid, inst->queue_total,
                          inst->copy_mode, inst->copy_range,
                          inst->queue_dropped, inst->queue_user_dropped,
                          inst->id_sequence, 1);
index 6bf878335d9436d40b1619c37c8918f3bd12beb0..c15042f987bd8f5697338b88cc77ed6553a0d609 100644 (file)
@@ -627,7 +627,7 @@ static int netlbl_cipsov4_listall_cb(struct cipso_v4_doi *doi_def, void *arg)
        struct netlbl_cipsov4_doiwalk_arg *cb_arg = arg;
        void *data;
 
-       data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).pid,
+       data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
                           cb_arg->seq, &netlbl_cipsov4_gnl_family,
                           NLM_F_MULTI, NLBL_CIPSOV4_C_LISTALL);
        if (data == NULL)
index 4809e2e48b02542931d436188680f9663a6dd699..c5384ffc61469a422f1e5f4a9519131d95b56236 100644 (file)
@@ -448,7 +448,7 @@ static int netlbl_mgmt_listall_cb(struct netlbl_dom_map *entry, void *arg)
        struct netlbl_domhsh_walk_arg *cb_arg = arg;
        void *data;
 
-       data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).pid,
+       data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
                           cb_arg->seq, &netlbl_mgmt_gnl_family,
                           NLM_F_MULTI, NLBL_MGMT_C_LISTALL);
        if (data == NULL)
@@ -613,7 +613,7 @@ static int netlbl_mgmt_protocols_cb(struct sk_buff *skb,
        int ret_val = -ENOMEM;
        void *data;
 
-       data = genlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
+       data = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
                           &netlbl_mgmt_gnl_family, NLM_F_MULTI,
                           NLBL_MGMT_C_PROTOCOLS);
        if (data == NULL)
index e7ff694f1049be48b3193d4a0b3ffded63aecbcd..b7944413b4041bfaf7aa646f7a9cb8c8053a78ee 100644 (file)
@@ -1096,7 +1096,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
        char *secctx;
        u32 secctx_len;
 
-       data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).pid,
+       data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
                           cb_arg->seq, &netlbl_unlabel_gnl_family,
                           NLM_F_MULTI, cmd);
        if (data == NULL)
index 3821199171660f3a16a94cab75453aee52d9c89c..0f2e3ad69c473afb5f7fcdbc1cbb05b5c0be46f7 100644 (file)
@@ -67,8 +67,8 @@
 struct netlink_sock {
        /* struct sock has to be the first member of netlink_sock */
        struct sock             sk;
-       u32                     pid;
-       u32                     dst_pid;
+       u32                     portid;
+       u32                     dst_portid;
        u32                     dst_group;
        u32                     flags;
        u32                     subscriptions;
@@ -104,7 +104,7 @@ static inline int netlink_is_kernel(struct sock *sk)
        return nlk_sk(sk)->flags & NETLINK_KERNEL_SOCKET;
 }
 
-struct nl_pid_hash {
+struct nl_portid_hash {
        struct hlist_head       *table;
        unsigned long           rehash_time;
 
@@ -118,10 +118,10 @@ struct nl_pid_hash {
 };
 
 struct netlink_table {
-       struct nl_pid_hash      hash;
+       struct nl_portid_hash   hash;
        struct hlist_head       mc_list;
        struct listeners __rcu  *listeners;
-       unsigned int            nl_nonroot;
+       unsigned int            flags;
        unsigned int            groups;
        struct mutex            *cb_mutex;
        struct module           *module;
@@ -145,9 +145,9 @@ static inline u32 netlink_group_mask(u32 group)
        return group ? 1 << (group - 1) : 0;
 }
 
-static inline struct hlist_head *nl_pid_hashfn(struct nl_pid_hash *hash, u32 pid)
+static inline struct hlist_head *nl_portid_hashfn(struct nl_portid_hash *hash, u32 portid)
 {
-       return &hash->table[jhash_1word(pid, hash->rnd) & hash->mask];
+       return &hash->table[jhash_1word(portid, hash->rnd) & hash->mask];
 }
 
 static void netlink_destroy_callback(struct netlink_callback *cb)
@@ -239,17 +239,17 @@ netlink_unlock_table(void)
                wake_up(&nl_table_wait);
 }
 
-static struct sock *netlink_lookup(struct net *net, int protocol, u32 pid)
+static struct sock *netlink_lookup(struct net *net, int protocol, u32 portid)
 {
-       struct nl_pid_hash *hash = &nl_table[protocol].hash;
+       struct nl_portid_hash *hash = &nl_table[protocol].hash;
        struct hlist_head *head;
        struct sock *sk;
        struct hlist_node *node;
 
        read_lock(&nl_table_lock);
-       head = nl_pid_hashfn(hash, pid);
+       head = nl_portid_hashfn(hash, portid);
        sk_for_each(sk, node, head) {
-               if (net_eq(sock_net(sk), net) && (nlk_sk(sk)->pid == pid)) {
+               if (net_eq(sock_net(sk), net) && (nlk_sk(sk)->portid == portid)) {
                        sock_hold(sk);
                        goto found;
                }
@@ -260,7 +260,7 @@ found:
        return sk;
 }
 
-static struct hlist_head *nl_pid_hash_zalloc(size_t size)
+static struct hlist_head *nl_portid_hash_zalloc(size_t size)
 {
        if (size <= PAGE_SIZE)
                return kzalloc(size, GFP_ATOMIC);
@@ -270,7 +270,7 @@ static struct hlist_head *nl_pid_hash_zalloc(size_t size)
                                         get_order(size));
 }
 
-static void nl_pid_hash_free(struct hlist_head *table, size_t size)
+static void nl_portid_hash_free(struct hlist_head *table, size_t size)
 {
        if (size <= PAGE_SIZE)
                kfree(table);
@@ -278,7 +278,7 @@ static void nl_pid_hash_free(struct hlist_head *table, size_t size)
                free_pages((unsigned long)table, get_order(size));
 }
 
-static int nl_pid_hash_rehash(struct nl_pid_hash *hash, int grow)
+static int nl_portid_hash_rehash(struct nl_portid_hash *hash, int grow)
 {
        unsigned int omask, mask, shift;
        size_t osize, size;
@@ -296,7 +296,7 @@ static int nl_pid_hash_rehash(struct nl_pid_hash *hash, int grow)
                size *= 2;
        }
 
-       table = nl_pid_hash_zalloc(size);
+       table = nl_portid_hash_zalloc(size);
        if (!table)
                return 0;
 
@@ -311,23 +311,23 @@ static int nl_pid_hash_rehash(struct nl_pid_hash *hash, int grow)
                struct hlist_node *node, *tmp;
 
                sk_for_each_safe(sk, node, tmp, &otable[i])
-                       __sk_add_node(sk, nl_pid_hashfn(hash, nlk_sk(sk)->pid));
+                       __sk_add_node(sk, nl_portid_hashfn(hash, nlk_sk(sk)->portid));
        }
 
-       nl_pid_hash_free(otable, osize);
+       nl_portid_hash_free(otable, osize);
        hash->rehash_time = jiffies + 10 * 60 * HZ;
        return 1;
 }
 
-static inline int nl_pid_hash_dilute(struct nl_pid_hash *hash, int len)
+static inline int nl_portid_hash_dilute(struct nl_portid_hash *hash, int len)
 {
        int avg = hash->entries >> hash->shift;
 
-       if (unlikely(avg > 1) && nl_pid_hash_rehash(hash, 1))
+       if (unlikely(avg > 1) && nl_portid_hash_rehash(hash, 1))
                return 1;
 
        if (unlikely(len > avg) && time_after(jiffies, hash->rehash_time)) {
-               nl_pid_hash_rehash(hash, 0);
+               nl_portid_hash_rehash(hash, 0);
                return 1;
        }
 
@@ -356,9 +356,9 @@ netlink_update_listeners(struct sock *sk)
         * makes sure updates are visible before bind or setsockopt return. */
 }
 
-static int netlink_insert(struct sock *sk, struct net *net, u32 pid)
+static int netlink_insert(struct sock *sk, struct net *net, u32 portid)
 {
-       struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash;
+       struct nl_portid_hash *hash = &nl_table[sk->sk_protocol].hash;
        struct hlist_head *head;
        int err = -EADDRINUSE;
        struct sock *osk;
@@ -366,10 +366,10 @@ static int netlink_insert(struct sock *sk, struct net *net, u32 pid)
        int len;
 
        netlink_table_grab();
-       head = nl_pid_hashfn(hash, pid);
+       head = nl_portid_hashfn(hash, portid);
        len = 0;
        sk_for_each(osk, node, head) {
-               if (net_eq(sock_net(osk), net) && (nlk_sk(osk)->pid == pid))
+               if (net_eq(sock_net(osk), net) && (nlk_sk(osk)->portid == portid))
                        break;
                len++;
        }
@@ -377,17 +377,17 @@ static int netlink_insert(struct sock *sk, struct net *net, u32 pid)
                goto err;
 
        err = -EBUSY;
-       if (nlk_sk(sk)->pid)
+       if (nlk_sk(sk)->portid)
                goto err;
 
        err = -ENOMEM;
        if (BITS_PER_LONG > 32 && unlikely(hash->entries >= UINT_MAX))
                goto err;
 
-       if (len && nl_pid_hash_dilute(hash, len))
-               head = nl_pid_hashfn(hash, pid);
+       if (len && nl_portid_hash_dilute(hash, len))
+               head = nl_portid_hashfn(hash, portid);
        hash->entries++;
-       nlk_sk(sk)->pid = pid;
+       nlk_sk(sk)->portid = portid;
        sk_add_node(sk, head);
        err = 0;
 
@@ -518,11 +518,11 @@ static int netlink_release(struct socket *sock)
 
        skb_queue_purge(&sk->sk_write_queue);
 
-       if (nlk->pid) {
+       if (nlk->portid) {
                struct netlink_notify n = {
                                                .net = sock_net(sk),
                                                .protocol = sk->sk_protocol,
-                                               .pid = nlk->pid,
+                                               .portid = nlk->portid,
                                          };
                atomic_notifier_call_chain(&netlink_chain,
                                NETLINK_URELEASE, &n);
@@ -536,6 +536,8 @@ static int netlink_release(struct socket *sock)
                if (--nl_table[sk->sk_protocol].registered == 0) {
                        kfree(nl_table[sk->sk_protocol].listeners);
                        nl_table[sk->sk_protocol].module = NULL;
+                       nl_table[sk->sk_protocol].bind = NULL;
+                       nl_table[sk->sk_protocol].flags = 0;
                        nl_table[sk->sk_protocol].registered = 0;
                }
        } else if (nlk->subscriptions) {
@@ -557,24 +559,24 @@ static int netlink_autobind(struct socket *sock)
 {
        struct sock *sk = sock->sk;
        struct net *net = sock_net(sk);
-       struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash;
+       struct nl_portid_hash *hash = &nl_table[sk->sk_protocol].hash;
        struct hlist_head *head;
        struct sock *osk;
        struct hlist_node *node;
-       s32 pid = task_tgid_vnr(current);
+       s32 portid = task_tgid_vnr(current);
        int err;
        static s32 rover = -4097;
 
 retry:
        cond_resched();
        netlink_table_grab();
-       head = nl_pid_hashfn(hash, pid);
+       head = nl_portid_hashfn(hash, portid);
        sk_for_each(osk, node, head) {
                if (!net_eq(sock_net(osk), net))
                        continue;
-               if (nlk_sk(osk)->pid == pid) {
-                       /* Bind collision, search negative pid values. */
-                       pid = rover--;
+               if (nlk_sk(osk)->portid == portid) {
+                       /* Bind collision, search negative portid values. */
+                       portid = rover--;
                        if (rover > -4097)
                                rover = -4097;
                        netlink_table_ungrab();
@@ -583,7 +585,7 @@ retry:
        }
        netlink_table_ungrab();
 
-       err = netlink_insert(sk, net, pid);
+       err = netlink_insert(sk, net, portid);
        if (err == -EADDRINUSE)
                goto retry;
 
@@ -596,7 +598,7 @@ retry:
 
 static inline int netlink_capable(const struct socket *sock, unsigned int flag)
 {
-       return (nl_table[sock->sk->sk_protocol].nl_nonroot & flag) ||
+       return (nl_table[sock->sk->sk_protocol].flags & flag) ||
               capable(CAP_NET_ADMIN);
 }
 
@@ -659,15 +661,15 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
 
        /* Only superuser is allowed to listen multicasts */
        if (nladdr->nl_groups) {
-               if (!netlink_capable(sock, NL_NONROOT_RECV))
+               if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV))
                        return -EPERM;
                err = netlink_realloc_groups(sk);
                if (err)
                        return err;
        }
 
-       if (nlk->pid) {
-               if (nladdr->nl_pid != nlk->pid)
+       if (nlk->portid) {
+               if (nladdr->nl_pid != nlk->portid)
                        return -EINVAL;
        } else {
                err = nladdr->nl_pid ?
@@ -713,7 +715,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
 
        if (addr->sa_family == AF_UNSPEC) {
                sk->sk_state    = NETLINK_UNCONNECTED;
-               nlk->dst_pid    = 0;
+               nlk->dst_portid = 0;
                nlk->dst_group  = 0;
                return 0;
        }
@@ -721,15 +723,15 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
                return -EINVAL;
 
        /* Only superuser is allowed to send multicasts */
-       if (nladdr->nl_groups && !netlink_capable(sock, NL_NONROOT_SEND))
+       if (nladdr->nl_groups && !netlink_capable(sock, NL_CFG_F_NONROOT_SEND))
                return -EPERM;
 
-       if (!nlk->pid)
+       if (!nlk->portid)
                err = netlink_autobind(sock);
 
        if (err == 0) {
                sk->sk_state    = NETLINK_CONNECTED;
-               nlk->dst_pid    = nladdr->nl_pid;
+               nlk->dst_portid = nladdr->nl_pid;
                nlk->dst_group  = ffs(nladdr->nl_groups);
        }
 
@@ -748,10 +750,10 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr,
        *addr_len = sizeof(*nladdr);
 
        if (peer) {
-               nladdr->nl_pid = nlk->dst_pid;
+               nladdr->nl_pid = nlk->dst_portid;
                nladdr->nl_groups = netlink_group_mask(nlk->dst_group);
        } else {
-               nladdr->nl_pid = nlk->pid;
+               nladdr->nl_pid = nlk->portid;
                nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0;
        }
        return 0;
@@ -770,19 +772,19 @@ static void netlink_overrun(struct sock *sk)
        atomic_inc(&sk->sk_drops);
 }
 
-static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid)
+static struct sock *netlink_getsockbyportid(struct sock *ssk, u32 portid)
 {
        struct sock *sock;
        struct netlink_sock *nlk;
 
-       sock = netlink_lookup(sock_net(ssk), ssk->sk_protocol, pid);
+       sock = netlink_lookup(sock_net(ssk), ssk->sk_protocol, portid);
        if (!sock)
                return ERR_PTR(-ECONNREFUSED);
 
        /* Don't bother queuing skb if kernel socket has no input function */
        nlk = nlk_sk(sock);
        if (sock->sk_state == NETLINK_CONNECTED &&
-           nlk->dst_pid != nlk_sk(ssk)->pid) {
+           nlk->dst_portid != nlk_sk(ssk)->portid) {
                sock_put(sock);
                return ERR_PTR(-ECONNREFUSED);
        }
@@ -933,7 +935,7 @@ static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb,
 }
 
 int netlink_unicast(struct sock *ssk, struct sk_buff *skb,
-                   u32 pid, int nonblock)
+                   u32 portid, int nonblock)
 {
        struct sock *sk;
        int err;
@@ -943,7 +945,7 @@ int netlink_unicast(struct sock *ssk, struct sk_buff *skb,
 
        timeo = sock_sndtimeo(ssk, nonblock);
 retry:
-       sk = netlink_getsockbypid(ssk, pid);
+       sk = netlink_getsockbyportid(ssk, portid);
        if (IS_ERR(sk)) {
                kfree_skb(skb);
                return PTR_ERR(sk);
@@ -1003,7 +1005,7 @@ static int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb)
 struct netlink_broadcast_data {
        struct sock *exclude_sk;
        struct net *net;
-       u32 pid;
+       u32 portid;
        u32 group;
        int failure;
        int delivery_failure;
@@ -1024,7 +1026,7 @@ static int do_one_broadcast(struct sock *sk,
        if (p->exclude_sk == sk)
                goto out;
 
-       if (nlk->pid == p->pid || p->group - 1 >= nlk->ngroups ||
+       if (nlk->portid == p->portid || p->group - 1 >= nlk->ngroups ||
            !test_bit(p->group - 1, nlk->groups))
                goto out;
 
@@ -1076,7 +1078,7 @@ out:
        return 0;
 }
 
-int netlink_broadcast_filtered(struct sock *ssk, struct sk_buff *skb, u32 pid,
+int netlink_broadcast_filtered(struct sock *ssk, struct sk_buff *skb, u32 portid,
        u32 group, gfp_t allocation,
        int (*filter)(struct sock *dsk, struct sk_buff *skb, void *data),
        void *filter_data)
@@ -1090,7 +1092,7 @@ int netlink_broadcast_filtered(struct sock *ssk, struct sk_buff *skb, u32 pid,
 
        info.exclude_sk = ssk;
        info.net = net;
-       info.pid = pid;
+       info.portid = portid;
        info.group = group;
        info.failure = 0;
        info.delivery_failure = 0;
@@ -1128,17 +1130,17 @@ int netlink_broadcast_filtered(struct sock *ssk, struct sk_buff *skb, u32 pid,
 }
 EXPORT_SYMBOL(netlink_broadcast_filtered);
 
-int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid,
+int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 portid,
                      u32 group, gfp_t allocation)
 {
-       return netlink_broadcast_filtered(ssk, skb, pid, group, allocation,
+       return netlink_broadcast_filtered(ssk, skb, portid, group, allocation,
                NULL, NULL);
 }
 EXPORT_SYMBOL(netlink_broadcast);
 
 struct netlink_set_err_data {
        struct sock *exclude_sk;
-       u32 pid;
+       u32 portid;
        u32 group;
        int code;
 };
@@ -1154,7 +1156,7 @@ static int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p)
        if (!net_eq(sock_net(sk), sock_net(p->exclude_sk)))
                goto out;
 
-       if (nlk->pid == p->pid || p->group - 1 >= nlk->ngroups ||
+       if (nlk->portid == p->portid || p->group - 1 >= nlk->ngroups ||
            !test_bit(p->group - 1, nlk->groups))
                goto out;
 
@@ -1172,14 +1174,14 @@ out:
 /**
  * netlink_set_err - report error to broadcast listeners
  * @ssk: the kernel netlink socket, as returned by netlink_kernel_create()
- * @pid: the PID of a process that we want to skip (if any)
+ * @portid: the PORTID of a process that we want to skip (if any)
  * @groups: the broadcast group that will notice the error
  * @code: error code, must be negative (as usual in kernelspace)
  *
  * This function returns the number of broadcast listeners that have set the
  * NETLINK_RECV_NO_ENOBUFS socket option.
  */
-int netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
+int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code)
 {
        struct netlink_set_err_data info;
        struct hlist_node *node;
@@ -1187,7 +1189,7 @@ int netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
        int ret = 0;
 
        info.exclude_sk = ssk;
-       info.pid = pid;
+       info.portid = portid;
        info.group = group;
        /* sk->sk_err wants a positive error value */
        info.code = -code;
@@ -1244,7 +1246,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
                break;
        case NETLINK_ADD_MEMBERSHIP:
        case NETLINK_DROP_MEMBERSHIP: {
-               if (!netlink_capable(sock, NL_NONROOT_RECV))
+               if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV))
                        return -EPERM;
                err = netlink_realloc_groups(sk);
                if (err)
@@ -1352,7 +1354,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
        struct sock *sk = sock->sk;
        struct netlink_sock *nlk = nlk_sk(sk);
        struct sockaddr_nl *addr = msg->msg_name;
-       u32 dst_pid;
+       u32 dst_portid;
        u32 dst_group;
        struct sk_buff *skb;
        int err;
@@ -1372,18 +1374,18 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
                err = -EINVAL;
                if (addr->nl_family != AF_NETLINK)
                        goto out;
-               dst_pid = addr->nl_pid;
+               dst_portid = addr->nl_pid;
                dst_group = ffs(addr->nl_groups);
                err =  -EPERM;
-               if ((dst_group || dst_pid) &&
-                   !netlink_capable(sock, NL_NONROOT_SEND))
+               if ((dst_group || dst_portid) &&
+                   !netlink_capable(sock, NL_CFG_F_NONROOT_SEND))
                        goto out;
        } else {
-               dst_pid = nlk->dst_pid;
+               dst_portid = nlk->dst_portid;
                dst_group = nlk->dst_group;
        }
 
-       if (!nlk->pid) {
+       if (!nlk->portid) {
                err = netlink_autobind(sock);
                if (err)
                        goto out;
@@ -1397,9 +1399,9 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
        if (skb == NULL)
                goto out;
 
-       NETLINK_CB(skb).pid     = nlk->pid;
+       NETLINK_CB(skb).portid  = nlk->portid;
        NETLINK_CB(skb).dst_group = dst_group;
-       memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
+       NETLINK_CB(skb).creds   = siocb->scm->creds;
 
        err = -EFAULT;
        if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
@@ -1415,9 +1417,9 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
 
        if (dst_group) {
                atomic_inc(&skb->users);
-               netlink_broadcast(sk, skb, dst_pid, dst_group, GFP_KERNEL);
+               netlink_broadcast(sk, skb, dst_portid, dst_group, GFP_KERNEL);
        }
-       err = netlink_unicast(sk, skb, dst_pid, msg->msg_flags&MSG_DONTWAIT);
+       err = netlink_unicast(sk, skb, dst_portid, msg->msg_flags&MSG_DONTWAIT);
 
 out:
        scm_destroy(siocb->scm);
@@ -1480,7 +1482,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
                struct sockaddr_nl *addr = (struct sockaddr_nl *)msg->msg_name;
                addr->nl_family = AF_NETLINK;
                addr->nl_pad    = 0;
-               addr->nl_pid    = NETLINK_CB(skb).pid;
+               addr->nl_pid    = NETLINK_CB(skb).portid;
                addr->nl_groups = netlink_group_mask(NETLINK_CB(skb).dst_group);
                msg->msg_namelen = sizeof(*addr);
        }
@@ -1524,9 +1526,8 @@ static void netlink_data_ready(struct sock *sk, int len)
  */
 
 struct sock *
-netlink_kernel_create(struct net *net, int unit,
-                     struct module *module,
-                     struct netlink_kernel_cfg *cfg)
+__netlink_kernel_create(struct net *net, int unit, struct module *module,
+                       struct netlink_kernel_cfg *cfg)
 {
        struct socket *sock;
        struct sock *sk;
@@ -1580,7 +1581,10 @@ netlink_kernel_create(struct net *net, int unit,
                rcu_assign_pointer(nl_table[unit].listeners, listeners);
                nl_table[unit].cb_mutex = cb_mutex;
                nl_table[unit].module = module;
-               nl_table[unit].bind = cfg ? cfg->bind : NULL;
+               if (cfg) {
+                       nl_table[unit].bind = cfg->bind;
+                       nl_table[unit].flags = cfg->flags;
+               }
                nl_table[unit].registered = 1;
        } else {
                kfree(listeners);
@@ -1598,8 +1602,7 @@ out_sock_release_nosk:
        sock_release(sock);
        return NULL;
 }
-EXPORT_SYMBOL(netlink_kernel_create);
-
+EXPORT_SYMBOL(__netlink_kernel_create);
 
 void
 netlink_kernel_release(struct sock *sk)
@@ -1679,15 +1682,8 @@ void netlink_clear_multicast_users(struct sock *ksk, unsigned int group)
        netlink_table_ungrab();
 }
 
-void netlink_set_nonroot(int protocol, unsigned int flags)
-{
-       if ((unsigned int)protocol < MAX_LINKS)
-               nl_table[protocol].nl_nonroot = flags;
-}
-EXPORT_SYMBOL(netlink_set_nonroot);
-
 struct nlmsghdr *
-__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
+__nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, int type, int len, int flags)
 {
        struct nlmsghdr *nlh;
        int size = NLMSG_LENGTH(len);
@@ -1696,7 +1692,7 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
        nlh->nlmsg_type = type;
        nlh->nlmsg_len = size;
        nlh->nlmsg_flags = flags;
-       nlh->nlmsg_pid = pid;
+       nlh->nlmsg_pid = portid;
        nlh->nlmsg_seq = seq;
        if (!__builtin_constant_p(size) || NLMSG_ALIGN(size) - size != 0)
                memset(NLMSG_DATA(nlh) + len, 0, NLMSG_ALIGN(size) - size);
@@ -1792,7 +1788,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
        atomic_inc(&skb->users);
        cb->skb = skb;
 
-       sk = netlink_lookup(sock_net(ssk), ssk->sk_protocol, NETLINK_CB(skb).pid);
+       sk = netlink_lookup(sock_net(ssk), ssk->sk_protocol, NETLINK_CB(skb).portid);
        if (sk == NULL) {
                netlink_destroy_callback(cb);
                return -ECONNREFUSED;
@@ -1840,7 +1836,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
 
                sk = netlink_lookup(sock_net(in_skb->sk),
                                    in_skb->sk->sk_protocol,
-                                   NETLINK_CB(in_skb).pid);
+                                   NETLINK_CB(in_skb).portid);
                if (sk) {
                        sk->sk_err = ENOBUFS;
                        sk->sk_error_report(sk);
@@ -1849,12 +1845,12 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
                return;
        }
 
-       rep = __nlmsg_put(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
+       rep = __nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
                          NLMSG_ERROR, payload, 0);
        errmsg = nlmsg_data(rep);
        errmsg->error = err;
        memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(*nlh));
-       netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
+       netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid, MSG_DONTWAIT);
 }
 EXPORT_SYMBOL(netlink_ack);
 
@@ -1904,33 +1900,33 @@ EXPORT_SYMBOL(netlink_rcv_skb);
  * nlmsg_notify - send a notification netlink message
  * @sk: netlink socket to use
  * @skb: notification message
- * @pid: destination netlink pid for reports or 0
+ * @portid: destination netlink portid for reports or 0
  * @group: destination multicast group or 0
  * @report: 1 to report back, 0 to disable
  * @flags: allocation flags
  */
-int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid,
+int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 portid,
                 unsigned int group, int report, gfp_t flags)
 {
        int err = 0;
 
        if (group) {
-               int exclude_pid = 0;
+               int exclude_portid = 0;
 
                if (report) {
                        atomic_inc(&skb->users);
-                       exclude_pid = pid;
+                       exclude_portid = portid;
                }
 
                /* errors reported via destination sk->sk_err, but propagate
                 * delivery errors if NETLINK_BROADCAST_ERROR flag is set */
-               err = nlmsg_multicast(sk, skb, exclude_pid, group, flags);
+               err = nlmsg_multicast(sk, skb, exclude_portid, group, flags);
        }
 
        if (report) {
                int err2;
 
-               err2 = nlmsg_unicast(sk, skb, pid);
+               err2 = nlmsg_unicast(sk, skb, portid);
                if (!err || err == -ESRCH)
                        err = err2;
        }
@@ -1955,7 +1951,7 @@ static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos)
        loff_t off = 0;
 
        for (i = 0; i < MAX_LINKS; i++) {
-               struct nl_pid_hash *hash = &nl_table[i].hash;
+               struct nl_portid_hash *hash = &nl_table[i].hash;
 
                for (j = 0; j <= hash->mask; j++) {
                        sk_for_each(s, node, &hash->table[j]) {
@@ -2003,7 +1999,7 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
        j = iter->hash_idx + 1;
 
        do {
-               struct nl_pid_hash *hash = &nl_table[i].hash;
+               struct nl_portid_hash *hash = &nl_table[i].hash;
 
                for (; j <= hash->mask; j++) {
                        s = sk_head(&hash->table[j]);
@@ -2042,7 +2038,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
                seq_printf(seq, "%pK %-3d %-6d %08x %-8d %-8d %pK %-8d %-8d %-8lu\n",
                           s,
                           s->sk_protocol,
-                          nlk->pid,
+                          nlk->portid,
                           nlk->groups ? (u32)nlk->groups[0] : 0,
                           sk_rmem_alloc_get(s),
                           sk_wmem_alloc_get(s),
@@ -2150,7 +2146,7 @@ static void __init netlink_add_usersock_entry(void)
        rcu_assign_pointer(nl_table[NETLINK_USERSOCK].listeners, listeners);
        nl_table[NETLINK_USERSOCK].module = THIS_MODULE;
        nl_table[NETLINK_USERSOCK].registered = 1;
-       nl_table[NETLINK_USERSOCK].nl_nonroot = NL_NONROOT_SEND;
+       nl_table[NETLINK_USERSOCK].flags = NL_CFG_F_NONROOT_SEND;
 
        netlink_table_ungrab();
 }
@@ -2187,12 +2183,12 @@ static int __init netlink_proto_init(void)
        order = get_bitmask_order(min(limit, (unsigned long)UINT_MAX)) - 1;
 
        for (i = 0; i < MAX_LINKS; i++) {
-               struct nl_pid_hash *hash = &nl_table[i].hash;
+               struct nl_portid_hash *hash = &nl_table[i].hash;
 
-               hash->table = nl_pid_hash_zalloc(1 * sizeof(*hash->table));
+               hash->table = nl_portid_hash_zalloc(1 * sizeof(*hash->table));
                if (!hash->table) {
                        while (i-- > 0)
-                               nl_pid_hash_free(nl_table[i].hash.table,
+                               nl_portid_hash_free(nl_table[i].hash.table,
                                                 1 * sizeof(*hash->table));
                        kfree(nl_table);
                        goto panic;
index fda497412fc34a5b10aa25a1c7599118d5e832a8..f2aabb6f410582439604d7a3c0f379a5cd798621 100644 (file)
@@ -501,7 +501,7 @@ EXPORT_SYMBOL(genl_unregister_family);
 /**
  * genlmsg_put - Add generic netlink header to netlink message
  * @skb: socket buffer holding the message
- * @pid: netlink pid the message is addressed to
+ * @portid: netlink portid the message is addressed to
  * @seq: sequence number (usually the one of the sender)
  * @family: generic netlink family
  * @flags: netlink message flags
@@ -509,13 +509,13 @@ EXPORT_SYMBOL(genl_unregister_family);
  *
  * Returns pointer to user specific header
  */
-void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
+void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
                                struct genl_family *family, int flags, u8 cmd)
 {
        struct nlmsghdr *nlh;
        struct genlmsghdr *hdr;
 
-       nlh = nlmsg_put(skb, pid, seq, family->id, GENL_HDRLEN +
+       nlh = nlmsg_put(skb, portid, seq, family->id, GENL_HDRLEN +
                        family->hdrsize, flags);
        if (nlh == NULL)
                return NULL;
@@ -585,7 +585,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        }
 
        info.snd_seq = nlh->nlmsg_seq;
-       info.snd_pid = NETLINK_CB(skb).pid;
+       info.snd_portid = NETLINK_CB(skb).portid;
        info.nlhdr = nlh;
        info.genlhdr = nlmsg_data(nlh);
        info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
@@ -626,12 +626,12 @@ static struct genl_family genl_ctrl = {
        .netnsok = true,
 };
 
-static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
+static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq,
                          u32 flags, struct sk_buff *skb, u8 cmd)
 {
        void *hdr;
 
-       hdr = genlmsg_put(skb, pid, seq, &genl_ctrl, flags, cmd);
+       hdr = genlmsg_put(skb, portid, seq, &genl_ctrl, flags, cmd);
        if (hdr == NULL)
                return -1;
 
@@ -701,7 +701,7 @@ nla_put_failure:
        return -EMSGSIZE;
 }
 
-static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 pid,
+static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 portid,
                                u32 seq, u32 flags, struct sk_buff *skb,
                                u8 cmd)
 {
@@ -709,7 +709,7 @@ static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 pid,
        struct nlattr *nla_grps;
        struct nlattr *nest;
 
-       hdr = genlmsg_put(skb, pid, seq, &genl_ctrl, flags, cmd);
+       hdr = genlmsg_put(skb, portid, seq, &genl_ctrl, flags, cmd);
        if (hdr == NULL)
                return -1;
 
@@ -756,7 +756,7 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
                                continue;
                        if (++n < fams_to_skip)
                                continue;
-                       if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).pid,
+                       if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).portid,
                                           cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                           skb, CTRL_CMD_NEWFAMILY) < 0)
                                goto errout;
@@ -773,7 +773,7 @@ errout:
 }
 
 static struct sk_buff *ctrl_build_family_msg(struct genl_family *family,
-                                            u32 pid, int seq, u8 cmd)
+                                            u32 portid, int seq, u8 cmd)
 {
        struct sk_buff *skb;
        int err;
@@ -782,7 +782,7 @@ static struct sk_buff *ctrl_build_family_msg(struct genl_family *family,
        if (skb == NULL)
                return ERR_PTR(-ENOBUFS);
 
-       err = ctrl_fill_info(family, pid, seq, 0, skb, cmd);
+       err = ctrl_fill_info(family, portid, seq, 0, skb, cmd);
        if (err < 0) {
                nlmsg_free(skb);
                return ERR_PTR(err);
@@ -792,7 +792,7 @@ static struct sk_buff *ctrl_build_family_msg(struct genl_family *family,
 }
 
 static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp,
-                                           u32 pid, int seq, u8 cmd)
+                                           u32 portid, int seq, u8 cmd)
 {
        struct sk_buff *skb;
        int err;
@@ -801,7 +801,7 @@ static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp,
        if (skb == NULL)
                return ERR_PTR(-ENOBUFS);
 
-       err = ctrl_fill_mcgrp_info(grp, pid, seq, 0, skb, cmd);
+       err = ctrl_fill_mcgrp_info(grp, portid, seq, 0, skb, cmd);
        if (err < 0) {
                nlmsg_free(skb);
                return ERR_PTR(err);
@@ -853,7 +853,7 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
                return -ENOENT;
        }
 
-       msg = ctrl_build_family_msg(res, info->snd_pid, info->snd_seq,
+       msg = ctrl_build_family_msg(res, info->snd_portid, info->snd_seq,
                                    CTRL_CMD_NEWFAMILY);
        if (IS_ERR(msg))
                return PTR_ERR(msg);
@@ -918,11 +918,11 @@ static int __net_init genl_pernet_init(struct net *net)
        struct netlink_kernel_cfg cfg = {
                .input          = genl_rcv,
                .cb_mutex       = &genl_mutex,
+               .flags          = NL_CFG_F_NONROOT_RECV,
        };
 
        /* we'll bump the group number right afterwards */
-       net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC,
-                                              THIS_MODULE, &cfg);
+       net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC, &cfg);
 
        if (!net->genl_sock && net_eq(net, &init_net))
                panic("GENL: Cannot initialize generic netlink\n");
@@ -955,8 +955,6 @@ static int __init genl_init(void)
        if (err < 0)
                goto problem;
 
-       netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
-
        err = register_pernet_subsys(&genl_pernet_ops);
        if (err)
                goto problem;
@@ -973,7 +971,7 @@ problem:
 
 subsys_initcall(genl_init);
 
-static int genlmsg_mcast(struct sk_buff *skb, u32 pid, unsigned long group,
+static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
                         gfp_t flags)
 {
        struct sk_buff *tmp;
@@ -988,7 +986,7 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 pid, unsigned long group,
                                goto error;
                        }
                        err = nlmsg_multicast(prev->genl_sock, tmp,
-                                             pid, group, flags);
+                                             portid, group, flags);
                        if (err)
                                goto error;
                }
@@ -996,20 +994,20 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 pid, unsigned long group,
                prev = net;
        }
 
-       return nlmsg_multicast(prev->genl_sock, skb, pid, group, flags);
+       return nlmsg_multicast(prev->genl_sock, skb, portid, group, flags);
  error:
        kfree_skb(skb);
        return err;
 }
 
-int genlmsg_multicast_allns(struct sk_buff *skb, u32 pid, unsigned int group,
+int genlmsg_multicast_allns(struct sk_buff *skb, u32 portid, unsigned int group,
                            gfp_t flags)
 {
-       return genlmsg_mcast(skb, pid, group, flags);
+       return genlmsg_mcast(skb, portid, group, flags);
 }
 EXPORT_SYMBOL(genlmsg_multicast_allns);
 
-void genl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
+void genl_notify(struct sk_buff *skb, struct net *net, u32 portid, u32 group,
                 struct nlmsghdr *nlh, gfp_t flags)
 {
        struct sock *sk = net->genl_sock;
@@ -1018,6 +1016,6 @@ void genl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
        if (nlh)
                report = nlmsg_report(nlh);
 
-       nlmsg_notify(sk, skb, pid, group, report, flags);
+       nlmsg_notify(sk, skb, portid, group, report, flags);
 }
 EXPORT_SYMBOL(genl_notify);
index 4c51714ee74177509d6d7831c064e89280424ded..4bbb70e32d1e93e2a3ae122caed6d42c1d293fe0 100644 (file)
@@ -58,7 +58,7 @@ static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
 {
        void *hdr;
 
-       hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
+       hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
                          &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
        if (!hdr)
                return -EMSGSIZE;
@@ -165,7 +165,7 @@ int nfc_genl_targets_found(struct nfc_dev *dev)
        struct sk_buff *msg;
        void *hdr;
 
-       dev->genl_data.poll_req_pid = 0;
+       dev->genl_data.poll_req_portid = 0;
 
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
        if (!msg)
@@ -347,13 +347,13 @@ free_msg:
 }
 
 static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
-                               u32 pid, u32 seq,
+                               u32 portid, u32 seq,
                                struct netlink_callback *cb,
                                int flags)
 {
        void *hdr;
 
-       hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags,
+       hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, flags,
                          NFC_CMD_GET_DEVICE);
        if (!hdr)
                return -EMSGSIZE;
@@ -401,7 +401,7 @@ static int nfc_genl_dump_devices(struct sk_buff *skb,
        while (dev) {
                int rc;
 
-               rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid,
+               rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).portid,
                                          cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
                if (rc < 0)
                        break;
@@ -520,7 +520,7 @@ static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info)
                goto out_putdev;
        }
 
-       rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq,
+       rc = nfc_genl_send_device(msg, dev, info->snd_portid, info->snd_seq,
                                  NULL, 0);
        if (rc < 0)
                goto out_free;
@@ -611,7 +611,7 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
 
        rc = nfc_start_poll(dev, im_protocols, tm_protocols);
        if (!rc)
-               dev->genl_data.poll_req_pid = info->snd_pid;
+               dev->genl_data.poll_req_portid = info->snd_portid;
 
        mutex_unlock(&dev->genl_data.genl_data_mutex);
 
@@ -645,13 +645,13 @@ static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info)
 
        mutex_lock(&dev->genl_data.genl_data_mutex);
 
-       if (dev->genl_data.poll_req_pid != info->snd_pid) {
+       if (dev->genl_data.poll_req_portid != info->snd_portid) {
                rc = -EBUSY;
                goto out;
        }
 
        rc = nfc_stop_poll(dev);
-       dev->genl_data.poll_req_pid = 0;
+       dev->genl_data.poll_req_portid = 0;
 
 out:
        mutex_unlock(&dev->genl_data.genl_data_mutex);
@@ -771,15 +771,15 @@ static int nfc_genl_rcv_nl_event(struct notifier_block *this,
        if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC)
                goto out;
 
-       pr_debug("NETLINK_URELEASE event from id %d\n", n->pid);
+       pr_debug("NETLINK_URELEASE event from id %d\n", n->portid);
 
        nfc_device_iter_init(&iter);
        dev = nfc_device_iter_next(&iter);
 
        while (dev) {
-               if (dev->genl_data.poll_req_pid == n->pid) {
+               if (dev->genl_data.poll_req_portid == n->portid) {
                        nfc_stop_poll(dev);
-                       dev->genl_data.poll_req_pid = 0;
+                       dev->genl_data.poll_req_portid = 0;
                }
                dev = nfc_device_iter_next(&iter);
        }
@@ -792,7 +792,7 @@ out:
 
 void nfc_genl_data_init(struct nfc_genl_data *genl_data)
 {
-       genl_data->poll_req_pid = 0;
+       genl_data->poll_req_portid = 0;
        mutex_init(&genl_data->genl_data_mutex);
 }
 
index f3f96badf5aac0202a2bd54155d595b0373a18df..c7425f32e7db7c26a43a5e102711d97803befaf8 100644 (file)
@@ -266,7 +266,7 @@ static int do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
        if (unlikely(!skb))
                return -ENOMEM;
 
-       vport = rcu_dereference(dp->ports[out_port]);
+       vport = ovs_vport_rcu(dp, out_port);
        if (unlikely(!vport)) {
                kfree_skb(skb);
                return -ENODEV;
@@ -286,7 +286,7 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
        upcall.cmd = OVS_PACKET_CMD_ACTION;
        upcall.key = &OVS_CB(skb)->flow->key;
        upcall.userdata = NULL;
-       upcall.pid = 0;
+       upcall.portid = 0;
 
        for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
                 a = nla_next(a, &rem)) {
@@ -296,7 +296,7 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
                        break;
 
                case OVS_USERSPACE_ATTR_PID:
-                       upcall.pid = nla_get_u32(a);
+                       upcall.portid = nla_get_u32(a);
                        break;
                }
        }
index d8277d29e7102caf343d78b802f3371283c40de1..56327e877ed9cf5dfb6989a41f017cd27a4ead3f 100644 (file)
 #include <linux/dmi.h>
 #include <linux/workqueue.h>
 #include <net/genetlink.h>
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
 
 #include "datapath.h"
 #include "flow.h"
 #include "vport-internal_dev.h"
 
+/**
+ * struct ovs_net - Per net-namespace data for ovs.
+ * @dps: List of datapaths to enable dumping them all out.
+ * Protected by genl_mutex.
+ */
+struct ovs_net {
+       struct list_head dps;
+};
+
+static int ovs_net_id __read_mostly;
+
+#define REHASH_FLOW_INTERVAL (10 * 60 * HZ)
+static void rehash_flow_table(struct work_struct *work);
+static DECLARE_DELAYED_WORK(rehash_flow_wq, rehash_flow_table);
+
 /**
  * DOC: Locking:
  *
  * each other.
  */
 
-/* Global list of datapaths to enable dumping them all out.
- * Protected by genl_mutex.
- */
-static LIST_HEAD(dps);
-
-#define REHASH_FLOW_INTERVAL (10 * 60 * HZ)
-static void rehash_flow_table(struct work_struct *work);
-static DECLARE_DELAYED_WORK(rehash_flow_wq, rehash_flow_table);
-
 static struct vport *new_vport(const struct vport_parms *);
-static int queue_gso_packets(int dp_ifindex, struct sk_buff *,
+static int queue_gso_packets(struct net *, int dp_ifindex, struct sk_buff *,
                             const struct dp_upcall_info *);
-static int queue_userspace_packet(int dp_ifindex, struct sk_buff *,
+static int queue_userspace_packet(struct net *, int dp_ifindex,
+                                 struct sk_buff *,
                                  const struct dp_upcall_info *);
 
 /* Must be called with rcu_read_lock, genl_mutex, or RTNL lock. */
-static struct datapath *get_dp(int dp_ifindex)
+static struct datapath *get_dp(struct net *net, int dp_ifindex)
 {
        struct datapath *dp = NULL;
        struct net_device *dev;
 
        rcu_read_lock();
-       dev = dev_get_by_index_rcu(&init_net, dp_ifindex);
+       dev = dev_get_by_index_rcu(net, dp_ifindex);
        if (dev) {
                struct vport *vport = ovs_internal_dev_get_vport(dev);
                if (vport)
@@ -107,7 +116,7 @@ static struct datapath *get_dp(int dp_ifindex)
 /* Must be called with rcu_read_lock or RTNL lock. */
 const char *ovs_dp_name(const struct datapath *dp)
 {
-       struct vport *vport = rcu_dereference_rtnl(dp->ports[OVSP_LOCAL]);
+       struct vport *vport = ovs_vport_rtnl_rcu(dp, OVSP_LOCAL);
        return vport->ops->get_name(vport);
 }
 
@@ -118,7 +127,7 @@ static int get_dpifindex(struct datapath *dp)
 
        rcu_read_lock();
 
-       local = rcu_dereference(dp->ports[OVSP_LOCAL]);
+       local = ovs_vport_rcu(dp, OVSP_LOCAL);
        if (local)
                ifindex = local->ops->get_ifindex(local);
        else
@@ -135,9 +144,31 @@ static void destroy_dp_rcu(struct rcu_head *rcu)
 
        ovs_flow_tbl_destroy((__force struct flow_table *)dp->table);
        free_percpu(dp->stats_percpu);
+       release_net(ovs_dp_get_net(dp));
+       kfree(dp->ports);
        kfree(dp);
 }
 
+static struct hlist_head *vport_hash_bucket(const struct datapath *dp,
+                                           u16 port_no)
+{
+       return &dp->ports[port_no & (DP_VPORT_HASH_BUCKETS - 1)];
+}
+
+struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no)
+{
+       struct vport *vport;
+       struct hlist_node *n;
+       struct hlist_head *head;
+
+       head = vport_hash_bucket(dp, port_no);
+       hlist_for_each_entry_rcu(vport, n, head, dp_hash_node) {
+               if (vport->port_no == port_no)
+                       return vport;
+       }
+       return NULL;
+}
+
 /* Called with RTNL lock and genl_lock. */
 static struct vport *new_vport(const struct vport_parms *parms)
 {
@@ -146,9 +177,9 @@ static struct vport *new_vport(const struct vport_parms *parms)
        vport = ovs_vport_add(parms);
        if (!IS_ERR(vport)) {
                struct datapath *dp = parms->dp;
+               struct hlist_head *head = vport_hash_bucket(dp, vport->port_no);
 
-               rcu_assign_pointer(dp->ports[parms->port_no], vport);
-               list_add(&vport->node, &dp->port_list);
+               hlist_add_head_rcu(&vport->dp_hash_node, head);
        }
 
        return vport;
@@ -160,8 +191,7 @@ void ovs_dp_detach_port(struct vport *p)
        ASSERT_RTNL();
 
        /* First drop references to device. */
-       list_del(&p->node);
-       rcu_assign_pointer(p->dp->ports[p->port_no], NULL);
+       hlist_del_rcu(&p->dp_hash_node);
 
        /* Then destroy it. */
        ovs_vport_del(p);
@@ -195,7 +225,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
                upcall.cmd = OVS_PACKET_CMD_MISS;
                upcall.key = &key;
                upcall.userdata = NULL;
-               upcall.pid = p->upcall_pid;
+               upcall.portid = p->upcall_portid;
                ovs_dp_upcall(dp, skb, &upcall);
                consume_skb(skb);
                stats_counter = &stats->n_missed;
@@ -220,17 +250,18 @@ static struct genl_family dp_packet_genl_family = {
        .hdrsize = sizeof(struct ovs_header),
        .name = OVS_PACKET_FAMILY,
        .version = OVS_PACKET_VERSION,
-       .maxattr = OVS_PACKET_ATTR_MAX
+       .maxattr = OVS_PACKET_ATTR_MAX,
+       .netnsok = true
 };
 
 int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
-             const struct dp_upcall_info *upcall_info)
+                 const struct dp_upcall_info *upcall_info)
 {
        struct dp_stats_percpu *stats;
        int dp_ifindex;
        int err;
 
-       if (upcall_info->pid == 0) {
+       if (upcall_info->portid == 0) {
                err = -ENOTCONN;
                goto err;
        }
@@ -242,9 +273,9 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
        }
 
        if (!skb_is_gso(skb))
-               err = queue_userspace_packet(dp_ifindex, skb, upcall_info);
+               err = queue_userspace_packet(ovs_dp_get_net(dp), dp_ifindex, skb, upcall_info);
        else
-               err = queue_gso_packets(dp_ifindex, skb, upcall_info);
+               err = queue_gso_packets(ovs_dp_get_net(dp), dp_ifindex, skb, upcall_info);
        if (err)
                goto err;
 
@@ -260,7 +291,8 @@ err:
        return err;
 }
 
-static int queue_gso_packets(int dp_ifindex, struct sk_buff *skb,
+static int queue_gso_packets(struct net *net, int dp_ifindex,
+                            struct sk_buff *skb,
                             const struct dp_upcall_info *upcall_info)
 {
        unsigned short gso_type = skb_shinfo(skb)->gso_type;
@@ -276,7 +308,7 @@ static int queue_gso_packets(int dp_ifindex, struct sk_buff *skb,
        /* Queue all of the segments. */
        skb = segs;
        do {
-               err = queue_userspace_packet(dp_ifindex, skb, upcall_info);
+               err = queue_userspace_packet(net, dp_ifindex, skb, upcall_info);
                if (err)
                        break;
 
@@ -306,7 +338,8 @@ static int queue_gso_packets(int dp_ifindex, struct sk_buff *skb,
        return err;
 }
 
-static int queue_userspace_packet(int dp_ifindex, struct sk_buff *skb,
+static int queue_userspace_packet(struct net *net, int dp_ifindex,
+                                 struct sk_buff *skb,
                                  const struct dp_upcall_info *upcall_info)
 {
        struct ovs_header *upcall;
@@ -362,7 +395,7 @@ static int queue_userspace_packet(int dp_ifindex, struct sk_buff *skb,
 
        skb_copy_and_csum_dev(skb, nla_data(nla));
 
-       err = genlmsg_unicast(&init_net, user_skb, upcall_info->pid);
+       err = genlmsg_unicast(net, user_skb, upcall_info->portid);
 
 out:
        kfree_skb(nskb);
@@ -370,15 +403,10 @@ out:
 }
 
 /* Called with genl_mutex. */
-static int flush_flows(int dp_ifindex)
+static int flush_flows(struct datapath *dp)
 {
        struct flow_table *old_table;
        struct flow_table *new_table;
-       struct datapath *dp;
-
-       dp = get_dp(dp_ifindex);
-       if (!dp)
-               return -ENODEV;
 
        old_table = genl_dereference(dp->table);
        new_table = ovs_flow_tbl_alloc(TBL_MIN_BUCKETS);
@@ -668,7 +696,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
        packet->priority = flow->key.phy.priority;
 
        rcu_read_lock();
-       dp = get_dp(ovs_header->dp_ifindex);
+       dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
        err = -ENODEV;
        if (!dp)
                goto err_unlock;
@@ -742,7 +770,8 @@ static struct genl_family dp_flow_genl_family = {
        .hdrsize = sizeof(struct ovs_header),
        .name = OVS_FLOW_FAMILY,
        .version = OVS_FLOW_VERSION,
-       .maxattr = OVS_FLOW_ATTR_MAX
+       .maxattr = OVS_FLOW_ATTR_MAX,
+       .netnsok = true
 };
 
 static struct genl_multicast_group ovs_dp_flow_multicast_group = {
@@ -751,7 +780,7 @@ static struct genl_multicast_group ovs_dp_flow_multicast_group = {
 
 /* Called with genl_lock. */
 static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
-                                 struct sk_buff *skb, u32 pid,
+                                 struct sk_buff *skb, u32 portid,
                                  u32 seq, u32 flags, u8 cmd)
 {
        const int skb_orig_len = skb->len;
@@ -766,7 +795,7 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
        sf_acts = rcu_dereference_protected(flow->sf_acts,
                                            lockdep_genl_is_held());
 
-       ovs_header = genlmsg_put(skb, pid, seq, &dp_flow_genl_family, flags, cmd);
+       ovs_header = genlmsg_put(skb, portid, seq, &dp_flow_genl_family, flags, cmd);
        if (!ovs_header)
                return -EMSGSIZE;
 
@@ -850,7 +879,7 @@ static struct sk_buff *ovs_flow_cmd_alloc_info(struct sw_flow *flow)
 
 static struct sk_buff *ovs_flow_cmd_build_info(struct sw_flow *flow,
                                               struct datapath *dp,
-                                              u32 pid, u32 seq, u8 cmd)
+                                              u32 portid, u32 seq, u8 cmd)
 {
        struct sk_buff *skb;
        int retval;
@@ -859,7 +888,7 @@ static struct sk_buff *ovs_flow_cmd_build_info(struct sw_flow *flow,
        if (!skb)
                return ERR_PTR(-ENOMEM);
 
-       retval = ovs_flow_cmd_fill_info(flow, dp, skb, pid, seq, 0, cmd);
+       retval = ovs_flow_cmd_fill_info(flow, dp, skb, portid, seq, 0, cmd);
        BUG_ON(retval < 0);
        return skb;
 }
@@ -894,7 +923,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
                goto error;
        }
 
-       dp = get_dp(ovs_header->dp_ifindex);
+       dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
        error = -ENODEV;
        if (!dp)
                goto error;
@@ -941,7 +970,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
                flow->hash = ovs_flow_hash(&key, key_len);
                ovs_flow_tbl_insert(table, flow);
 
-               reply = ovs_flow_cmd_build_info(flow, dp, info->snd_pid,
+               reply = ovs_flow_cmd_build_info(flow, dp, info->snd_portid,
                                                info->snd_seq,
                                                OVS_FLOW_CMD_NEW);
        } else {
@@ -979,7 +1008,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
                        ovs_flow_deferred_free_acts(old_acts);
                }
 
-               reply = ovs_flow_cmd_build_info(flow, dp, info->snd_pid,
+               reply = ovs_flow_cmd_build_info(flow, dp, info->snd_portid,
                                               info->snd_seq, OVS_FLOW_CMD_NEW);
 
                /* Clear stats. */
@@ -991,11 +1020,11 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
        }
 
        if (!IS_ERR(reply))
-               genl_notify(reply, genl_info_net(info), info->snd_pid,
+               genl_notify(reply, genl_info_net(info), info->snd_portid,
                           ovs_dp_flow_multicast_group.id, info->nlhdr,
                           GFP_KERNEL);
        else
-               netlink_set_err(init_net.genl_sock, 0,
+               netlink_set_err(sock_net(skb->sk)->genl_sock, 0,
                                ovs_dp_flow_multicast_group.id, PTR_ERR(reply));
        return 0;
 
@@ -1023,7 +1052,7 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
        if (err)
                return err;
 
-       dp = get_dp(ovs_header->dp_ifindex);
+       dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
        if (!dp)
                return -ENODEV;
 
@@ -1032,7 +1061,7 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
        if (!flow)
                return -ENOENT;
 
-       reply = ovs_flow_cmd_build_info(flow, dp, info->snd_pid,
+       reply = ovs_flow_cmd_build_info(flow, dp, info->snd_portid,
                                        info->snd_seq, OVS_FLOW_CMD_NEW);
        if (IS_ERR(reply))
                return PTR_ERR(reply);
@@ -1052,16 +1081,17 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
        int err;
        int key_len;
 
+       dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
+       if (!dp)
+               return -ENODEV;
+
        if (!a[OVS_FLOW_ATTR_KEY])
-               return flush_flows(ovs_header->dp_ifindex);
+               return flush_flows(dp);
+
        err = ovs_flow_from_nlattrs(&key, &key_len, a[OVS_FLOW_ATTR_KEY]);
        if (err)
                return err;
 
-       dp = get_dp(ovs_header->dp_ifindex);
-       if (!dp)
-               return -ENODEV;
-
        table = genl_dereference(dp->table);
        flow = ovs_flow_tbl_lookup(table, &key, key_len);
        if (!flow)
@@ -1073,13 +1103,13 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
 
        ovs_flow_tbl_remove(table, flow);
 
-       err = ovs_flow_cmd_fill_info(flow, dp, reply, info->snd_pid,
+       err = ovs_flow_cmd_fill_info(flow, dp, reply, info->snd_portid,
                                     info->snd_seq, 0, OVS_FLOW_CMD_DEL);
        BUG_ON(err < 0);
 
        ovs_flow_deferred_free(flow);
 
-       genl_notify(reply, genl_info_net(info), info->snd_pid,
+       genl_notify(reply, genl_info_net(info), info->snd_portid,
                    ovs_dp_flow_multicast_group.id, info->nlhdr, GFP_KERNEL);
        return 0;
 }
@@ -1090,7 +1120,7 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
        struct datapath *dp;
        struct flow_table *table;
 
-       dp = get_dp(ovs_header->dp_ifindex);
+       dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
        if (!dp)
                return -ENODEV;
 
@@ -1107,7 +1137,7 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
                        break;
 
                if (ovs_flow_cmd_fill_info(flow, dp, skb,
-                                          NETLINK_CB(cb->skb).pid,
+                                          NETLINK_CB(cb->skb).portid,
                                           cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                           OVS_FLOW_CMD_NEW) < 0)
                        break;
@@ -1152,7 +1182,8 @@ static struct genl_family dp_datapath_genl_family = {
        .hdrsize = sizeof(struct ovs_header),
        .name = OVS_DATAPATH_FAMILY,
        .version = OVS_DATAPATH_VERSION,
-       .maxattr = OVS_DP_ATTR_MAX
+       .maxattr = OVS_DP_ATTR_MAX,
+       .netnsok = true
 };
 
 static struct genl_multicast_group ovs_dp_datapath_multicast_group = {
@@ -1160,13 +1191,13 @@ static struct genl_multicast_group ovs_dp_datapath_multicast_group = {
 };
 
 static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
-                               u32 pid, u32 seq, u32 flags, u8 cmd)
+                               u32 portid, u32 seq, u32 flags, u8 cmd)
 {
        struct ovs_header *ovs_header;
        struct ovs_dp_stats dp_stats;
        int err;
 
-       ovs_header = genlmsg_put(skb, pid, seq, &dp_datapath_genl_family,
+       ovs_header = genlmsg_put(skb, portid, seq, &dp_datapath_genl_family,
                                   flags, cmd);
        if (!ovs_header)
                goto error;
@@ -1191,7 +1222,7 @@ error:
        return -EMSGSIZE;
 }
 
-static struct sk_buff *ovs_dp_cmd_build_info(struct datapath *dp, u32 pid,
+static struct sk_buff *ovs_dp_cmd_build_info(struct datapath *dp, u32 portid,
                                             u32 seq, u8 cmd)
 {
        struct sk_buff *skb;
@@ -1201,7 +1232,7 @@ static struct sk_buff *ovs_dp_cmd_build_info(struct datapath *dp, u32 pid,
        if (!skb)
                return ERR_PTR(-ENOMEM);
 
-       retval = ovs_dp_cmd_fill_info(dp, skb, pid, seq, 0, cmd);
+       retval = ovs_dp_cmd_fill_info(dp, skb, portid, seq, 0, cmd);
        if (retval < 0) {
                kfree_skb(skb);
                return ERR_PTR(retval);
@@ -1210,18 +1241,19 @@ static struct sk_buff *ovs_dp_cmd_build_info(struct datapath *dp, u32 pid,
 }
 
 /* Called with genl_mutex and optionally with RTNL lock also. */
-static struct datapath *lookup_datapath(struct ovs_header *ovs_header,
+static struct datapath *lookup_datapath(struct net *net,
+                                       struct ovs_header *ovs_header,
                                        struct nlattr *a[OVS_DP_ATTR_MAX + 1])
 {
        struct datapath *dp;
 
        if (!a[OVS_DP_ATTR_NAME])
-               dp = get_dp(ovs_header->dp_ifindex);
+               dp = get_dp(net, ovs_header->dp_ifindex);
        else {
                struct vport *vport;
 
                rcu_read_lock();
-               vport = ovs_vport_locate(nla_data(a[OVS_DP_ATTR_NAME]));
+               vport = ovs_vport_locate(net, nla_data(a[OVS_DP_ATTR_NAME]));
                dp = vport && vport->port_no == OVSP_LOCAL ? vport->dp : NULL;
                rcu_read_unlock();
        }
@@ -1235,22 +1267,21 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
        struct sk_buff *reply;
        struct datapath *dp;
        struct vport *vport;
-       int err;
+       struct ovs_net *ovs_net;
+       int err, i;
 
        err = -EINVAL;
        if (!a[OVS_DP_ATTR_NAME] || !a[OVS_DP_ATTR_UPCALL_PID])
                goto err;
 
        rtnl_lock();
-       err = -ENODEV;
-       if (!try_module_get(THIS_MODULE))
-               goto err_unlock_rtnl;
 
        err = -ENOMEM;
        dp = kzalloc(sizeof(*dp), GFP_KERNEL);
        if (dp == NULL)
-               goto err_put_module;
-       INIT_LIST_HEAD(&dp->port_list);
+               goto err_unlock_rtnl;
+
+       ovs_dp_set_net(dp, hold_net(sock_net(skb->sk)));
 
        /* Allocate table. */
        err = -ENOMEM;
@@ -1264,13 +1295,23 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
                goto err_destroy_table;
        }
 
+       dp->ports = kmalloc(DP_VPORT_HASH_BUCKETS * sizeof(struct hlist_head),
+                       GFP_KERNEL);
+       if (!dp->ports) {
+               err = -ENOMEM;
+               goto err_destroy_percpu;
+       }
+
+       for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++)
+               INIT_HLIST_HEAD(&dp->ports[i]);
+
        /* Set up our datapath device. */
        parms.name = nla_data(a[OVS_DP_ATTR_NAME]);
        parms.type = OVS_VPORT_TYPE_INTERNAL;
        parms.options = NULL;
        parms.dp = dp;
        parms.port_no = OVSP_LOCAL;
-       parms.upcall_pid = nla_get_u32(a[OVS_DP_ATTR_UPCALL_PID]);
+       parms.upcall_portid = nla_get_u32(a[OVS_DP_ATTR_UPCALL_PID]);
 
        vport = new_vport(&parms);
        if (IS_ERR(vport)) {
@@ -1278,64 +1319,59 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
                if (err == -EBUSY)
                        err = -EEXIST;
 
-               goto err_destroy_percpu;
+               goto err_destroy_ports_array;
        }
 
-       reply = ovs_dp_cmd_build_info(dp, info->snd_pid,
+       reply = ovs_dp_cmd_build_info(dp, info->snd_portid,
                                      info->snd_seq, OVS_DP_CMD_NEW);
        err = PTR_ERR(reply);
        if (IS_ERR(reply))
                goto err_destroy_local_port;
 
-       list_add_tail(&dp->list_node, &dps);
+       ovs_net = net_generic(ovs_dp_get_net(dp), ovs_net_id);
+       list_add_tail(&dp->list_node, &ovs_net->dps);
        rtnl_unlock();
 
-       genl_notify(reply, genl_info_net(info), info->snd_pid,
+       genl_notify(reply, genl_info_net(info), info->snd_portid,
                    ovs_dp_datapath_multicast_group.id, info->nlhdr,
                    GFP_KERNEL);
        return 0;
 
 err_destroy_local_port:
-       ovs_dp_detach_port(rtnl_dereference(dp->ports[OVSP_LOCAL]));
+       ovs_dp_detach_port(ovs_vport_rtnl(dp, OVSP_LOCAL));
+err_destroy_ports_array:
+       kfree(dp->ports);
 err_destroy_percpu:
        free_percpu(dp->stats_percpu);
 err_destroy_table:
        ovs_flow_tbl_destroy(genl_dereference(dp->table));
 err_free_dp:
+       release_net(ovs_dp_get_net(dp));
        kfree(dp);
-err_put_module:
-       module_put(THIS_MODULE);
 err_unlock_rtnl:
        rtnl_unlock();
 err:
        return err;
 }
 
-static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info)
+/* Called with genl_mutex. */
+static void __dp_destroy(struct datapath *dp)
 {
-       struct vport *vport, *next_vport;
-       struct sk_buff *reply;
-       struct datapath *dp;
-       int err;
+       int i;
 
        rtnl_lock();
-       dp = lookup_datapath(info->userhdr, info->attrs);
-       err = PTR_ERR(dp);
-       if (IS_ERR(dp))
-               goto exit_unlock;
 
-       reply = ovs_dp_cmd_build_info(dp, info->snd_pid,
-                                     info->snd_seq, OVS_DP_CMD_DEL);
-       err = PTR_ERR(reply);
-       if (IS_ERR(reply))
-               goto exit_unlock;
+       for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) {
+               struct vport *vport;
+               struct hlist_node *node, *n;
 
-       list_for_each_entry_safe(vport, next_vport, &dp->port_list, node)
-               if (vport->port_no != OVSP_LOCAL)
-                       ovs_dp_detach_port(vport);
+               hlist_for_each_entry_safe(vport, node, n, &dp->ports[i], dp_hash_node)
+                       if (vport->port_no != OVSP_LOCAL)
+                               ovs_dp_detach_port(vport);
+       }
 
        list_del(&dp->list_node);
-       ovs_dp_detach_port(rtnl_dereference(dp->ports[OVSP_LOCAL]));
+       ovs_dp_detach_port(ovs_vport_rtnl(dp, OVSP_LOCAL));
 
        /* rtnl_unlock() will wait until all the references to devices that
         * are pending unregistration have been dropped.  We do it here to
@@ -1345,17 +1381,32 @@ static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info)
        rtnl_unlock();
 
        call_rcu(&dp->rcu, destroy_dp_rcu);
-       module_put(THIS_MODULE);
+}
+
+static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info)
+{
+       struct sk_buff *reply;
+       struct datapath *dp;
+       int err;
+
+       dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
+       err = PTR_ERR(dp);
+       if (IS_ERR(dp))
+               return err;
 
-       genl_notify(reply, genl_info_net(info), info->snd_pid,
+       reply = ovs_dp_cmd_build_info(dp, info->snd_portid,
+                                     info->snd_seq, OVS_DP_CMD_DEL);
+       err = PTR_ERR(reply);
+       if (IS_ERR(reply))
+               return err;
+
+       __dp_destroy(dp);
+
+       genl_notify(reply, genl_info_net(info), info->snd_portid,
                    ovs_dp_datapath_multicast_group.id, info->nlhdr,
                    GFP_KERNEL);
 
        return 0;
-
-exit_unlock:
-       rtnl_unlock();
-       return err;
 }
 
 static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info)
@@ -1364,20 +1415,20 @@ static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info)
        struct datapath *dp;
        int err;
 
-       dp = lookup_datapath(info->userhdr, info->attrs);
+       dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
        if (IS_ERR(dp))
                return PTR_ERR(dp);
 
-       reply = ovs_dp_cmd_build_info(dp, info->snd_pid,
+       reply = ovs_dp_cmd_build_info(dp, info->snd_portid,
                                      info->snd_seq, OVS_DP_CMD_NEW);
        if (IS_ERR(reply)) {
                err = PTR_ERR(reply);
-               netlink_set_err(init_net.genl_sock, 0,
+               netlink_set_err(sock_net(skb->sk)->genl_sock, 0,
                                ovs_dp_datapath_multicast_group.id, err);
                return 0;
        }
 
-       genl_notify(reply, genl_info_net(info), info->snd_pid,
+       genl_notify(reply, genl_info_net(info), info->snd_portid,
                    ovs_dp_datapath_multicast_group.id, info->nlhdr,
                    GFP_KERNEL);
 
@@ -1389,11 +1440,11 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
        struct sk_buff *reply;
        struct datapath *dp;
 
-       dp = lookup_datapath(info->userhdr, info->attrs);
+       dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
        if (IS_ERR(dp))
                return PTR_ERR(dp);
 
-       reply = ovs_dp_cmd_build_info(dp, info->snd_pid,
+       reply = ovs_dp_cmd_build_info(dp, info->snd_portid,
                                      info->snd_seq, OVS_DP_CMD_NEW);
        if (IS_ERR(reply))
                return PTR_ERR(reply);
@@ -1403,13 +1454,14 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
 
 static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct ovs_net *ovs_net = net_generic(sock_net(skb->sk), ovs_net_id);
        struct datapath *dp;
        int skip = cb->args[0];
        int i = 0;
 
-       list_for_each_entry(dp, &dps, list_node) {
+       list_for_each_entry(dp, &ovs_net->dps, list_node) {
                if (i >= skip &&
-                   ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).pid,
+                   ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid,
                                         cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                         OVS_DP_CMD_NEW) < 0)
                        break;
@@ -1459,7 +1511,8 @@ static struct genl_family dp_vport_genl_family = {
        .hdrsize = sizeof(struct ovs_header),
        .name = OVS_VPORT_FAMILY,
        .version = OVS_VPORT_VERSION,
-       .maxattr = OVS_VPORT_ATTR_MAX
+       .maxattr = OVS_VPORT_ATTR_MAX,
+       .netnsok = true
 };
 
 struct genl_multicast_group ovs_dp_vport_multicast_group = {
@@ -1468,13 +1521,13 @@ struct genl_multicast_group ovs_dp_vport_multicast_group = {
 
 /* Called with RTNL lock or RCU read lock. */
 static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
-                                  u32 pid, u32 seq, u32 flags, u8 cmd)
+                                  u32 portid, u32 seq, u32 flags, u8 cmd)
 {
        struct ovs_header *ovs_header;
        struct ovs_vport_stats vport_stats;
        int err;
 
-       ovs_header = genlmsg_put(skb, pid, seq, &dp_vport_genl_family,
+       ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family,
                                 flags, cmd);
        if (!ovs_header)
                return -EMSGSIZE;
@@ -1484,7 +1537,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
        if (nla_put_u32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no) ||
            nla_put_u32(skb, OVS_VPORT_ATTR_TYPE, vport->ops->type) ||
            nla_put_string(skb, OVS_VPORT_ATTR_NAME, vport->ops->get_name(vport)) ||
-           nla_put_u32(skb, OVS_VPORT_ATTR_UPCALL_PID, vport->upcall_pid))
+           nla_put_u32(skb, OVS_VPORT_ATTR_UPCALL_PID, vport->upcall_portid))
                goto nla_put_failure;
 
        ovs_vport_get_stats(vport, &vport_stats);
@@ -1506,7 +1559,7 @@ error:
 }
 
 /* Called with RTNL lock or RCU read lock. */
-struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 pid,
+struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 portid,
                                         u32 seq, u8 cmd)
 {
        struct sk_buff *skb;
@@ -1516,7 +1569,7 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 pid,
        if (!skb)
                return ERR_PTR(-ENOMEM);
 
-       retval = ovs_vport_cmd_fill_info(vport, skb, pid, seq, 0, cmd);
+       retval = ovs_vport_cmd_fill_info(vport, skb, portid, seq, 0, cmd);
        if (retval < 0) {
                kfree_skb(skb);
                return ERR_PTR(retval);
@@ -1525,14 +1578,15 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 pid,
 }
 
 /* Called with RTNL lock or RCU read lock. */
-static struct vport *lookup_vport(struct ovs_header *ovs_header,
+static struct vport *lookup_vport(struct net *net,
+                                 struct ovs_header *ovs_header,
                                  struct nlattr *a[OVS_VPORT_ATTR_MAX + 1])
 {
        struct datapath *dp;
        struct vport *vport;
 
        if (a[OVS_VPORT_ATTR_NAME]) {
-               vport = ovs_vport_locate(nla_data(a[OVS_VPORT_ATTR_NAME]));
+               vport = ovs_vport_locate(net, nla_data(a[OVS_VPORT_ATTR_NAME]));
                if (!vport)
                        return ERR_PTR(-ENODEV);
                if (ovs_header->dp_ifindex &&
@@ -1545,11 +1599,11 @@ static struct vport *lookup_vport(struct ovs_header *ovs_header,
                if (port_no >= DP_MAX_PORTS)
                        return ERR_PTR(-EFBIG);
 
-               dp = get_dp(ovs_header->dp_ifindex);
+               dp = get_dp(net, ovs_header->dp_ifindex);
                if (!dp)
                        return ERR_PTR(-ENODEV);
 
-               vport = rcu_dereference_rtnl(dp->ports[port_no]);
+               vport = ovs_vport_rtnl_rcu(dp, port_no);
                if (!vport)
                        return ERR_PTR(-ENOENT);
                return vport;
@@ -1574,7 +1628,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
                goto exit;
 
        rtnl_lock();
-       dp = get_dp(ovs_header->dp_ifindex);
+       dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
        err = -ENODEV;
        if (!dp)
                goto exit_unlock;
@@ -1586,7 +1640,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
                if (port_no >= DP_MAX_PORTS)
                        goto exit_unlock;
 
-               vport = rtnl_dereference(dp->ports[port_no]);
+               vport = ovs_vport_rtnl_rcu(dp, port_no);
                err = -EBUSY;
                if (vport)
                        goto exit_unlock;
@@ -1596,7 +1650,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
                                err = -EFBIG;
                                goto exit_unlock;
                        }
-                       vport = rtnl_dereference(dp->ports[port_no]);
+                       vport = ovs_vport_rtnl(dp, port_no);
                        if (!vport)
                                break;
                }
@@ -1607,21 +1661,21 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
        parms.options = a[OVS_VPORT_ATTR_OPTIONS];
        parms.dp = dp;
        parms.port_no = port_no;
-       parms.upcall_pid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
+       parms.upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
 
        vport = new_vport(&parms);
        err = PTR_ERR(vport);
        if (IS_ERR(vport))
                goto exit_unlock;
 
-       reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq,
+       reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq,
                                         OVS_VPORT_CMD_NEW);
        if (IS_ERR(reply)) {
                err = PTR_ERR(reply);
                ovs_dp_detach_port(vport);
                goto exit_unlock;
        }
-       genl_notify(reply, genl_info_net(info), info->snd_pid,
+       genl_notify(reply, genl_info_net(info), info->snd_portid,
                    ovs_dp_vport_multicast_group.id, info->nlhdr, GFP_KERNEL);
 
 exit_unlock:
@@ -1638,7 +1692,7 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
        int err;
 
        rtnl_lock();
-       vport = lookup_vport(info->userhdr, a);
+       vport = lookup_vport(sock_net(skb->sk), info->userhdr, a);
        err = PTR_ERR(vport);
        if (IS_ERR(vport))
                goto exit_unlock;
@@ -1653,17 +1707,17 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
        if (err)
                goto exit_unlock;
        if (a[OVS_VPORT_ATTR_UPCALL_PID])
-               vport->upcall_pid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
+               vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
 
-       reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq,
+       reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq,
                                         OVS_VPORT_CMD_NEW);
        if (IS_ERR(reply)) {
-               netlink_set_err(init_net.genl_sock, 0,
+               netlink_set_err(sock_net(skb->sk)->genl_sock, 0,
                                ovs_dp_vport_multicast_group.id, PTR_ERR(reply));
                goto exit_unlock;
        }
 
-       genl_notify(reply, genl_info_net(info), info->snd_pid,
+       genl_notify(reply, genl_info_net(info), info->snd_portid,
                    ovs_dp_vport_multicast_group.id, info->nlhdr, GFP_KERNEL);
 
 exit_unlock:
@@ -1679,7 +1733,7 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
        int err;
 
        rtnl_lock();
-       vport = lookup_vport(info->userhdr, a);
+       vport = lookup_vport(sock_net(skb->sk), info->userhdr, a);
        err = PTR_ERR(vport);
        if (IS_ERR(vport))
                goto exit_unlock;
@@ -1689,7 +1743,7 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
                goto exit_unlock;
        }
 
-       reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq,
+       reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq,
                                         OVS_VPORT_CMD_DEL);
        err = PTR_ERR(reply);
        if (IS_ERR(reply))
@@ -1697,7 +1751,7 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
 
        ovs_dp_detach_port(vport);
 
-       genl_notify(reply, genl_info_net(info), info->snd_pid,
+       genl_notify(reply, genl_info_net(info), info->snd_portid,
                    ovs_dp_vport_multicast_group.id, info->nlhdr, GFP_KERNEL);
 
 exit_unlock:
@@ -1714,12 +1768,12 @@ static int ovs_vport_cmd_get(struct sk_buff *skb, struct genl_info *info)
        int err;
 
        rcu_read_lock();
-       vport = lookup_vport(ovs_header, a);
+       vport = lookup_vport(sock_net(skb->sk), ovs_header, a);
        err = PTR_ERR(vport);
        if (IS_ERR(vport))
                goto exit_unlock;
 
-       reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq,
+       reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq,
                                         OVS_VPORT_CMD_NEW);
        err = PTR_ERR(reply);
        if (IS_ERR(reply))
@@ -1738,54 +1792,39 @@ static int ovs_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
 {
        struct ovs_header *ovs_header = genlmsg_data(nlmsg_data(cb->nlh));
        struct datapath *dp;
-       u32 port_no;
-       int retval;
+       int bucket = cb->args[0], skip = cb->args[1];
+       int i, j = 0;
 
-       dp = get_dp(ovs_header->dp_ifindex);
+       dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
        if (!dp)
                return -ENODEV;
 
        rcu_read_lock();
-       for (port_no = cb->args[0]; port_no < DP_MAX_PORTS; port_no++) {
+       for (i = bucket; i < DP_VPORT_HASH_BUCKETS; i++) {
                struct vport *vport;
-
-               vport = rcu_dereference(dp->ports[port_no]);
-               if (!vport)
-                       continue;
-
-               if (ovs_vport_cmd_fill_info(vport, skb, NETLINK_CB(cb->skb).pid,
-                                           cb->nlh->nlmsg_seq, NLM_F_MULTI,
-                                           OVS_VPORT_CMD_NEW) < 0)
-                       break;
-       }
-       rcu_read_unlock();
-
-       cb->args[0] = port_no;
-       retval = skb->len;
-
-       return retval;
-}
-
-static void rehash_flow_table(struct work_struct *work)
-{
-       struct datapath *dp;
-
-       genl_lock();
-
-       list_for_each_entry(dp, &dps, list_node) {
-               struct flow_table *old_table = genl_dereference(dp->table);
-               struct flow_table *new_table;
-
-               new_table = ovs_flow_tbl_rehash(old_table);
-               if (!IS_ERR(new_table)) {
-                       rcu_assign_pointer(dp->table, new_table);
-                       ovs_flow_tbl_deferred_destroy(old_table);
+               struct hlist_node *n;
+
+               j = 0;
+               hlist_for_each_entry_rcu(vport, n, &dp->ports[i], dp_hash_node) {
+                       if (j >= skip &&
+                           ovs_vport_cmd_fill_info(vport, skb,
+                                                   NETLINK_CB(cb->skb).portid,
+                                                   cb->nlh->nlmsg_seq,
+                                                   NLM_F_MULTI,
+                                                   OVS_VPORT_CMD_NEW) < 0)
+                               goto out;
+
+                       j++;
                }
+               skip = 0;
        }
+out:
+       rcu_read_unlock();
 
-       genl_unlock();
+       cb->args[0] = i;
+       cb->args[1] = j;
 
-       schedule_delayed_work(&rehash_flow_wq, REHASH_FLOW_INTERVAL);
+       return skb->len;
 }
 
 static struct genl_ops dp_vport_genl_ops[] = {
@@ -1872,6 +1911,59 @@ error:
        return err;
 }
 
+static void rehash_flow_table(struct work_struct *work)
+{
+       struct datapath *dp;
+       struct net *net;
+
+       genl_lock();
+       rtnl_lock();
+       for_each_net(net) {
+               struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
+
+               list_for_each_entry(dp, &ovs_net->dps, list_node) {
+                       struct flow_table *old_table = genl_dereference(dp->table);
+                       struct flow_table *new_table;
+
+                       new_table = ovs_flow_tbl_rehash(old_table);
+                       if (!IS_ERR(new_table)) {
+                               rcu_assign_pointer(dp->table, new_table);
+                               ovs_flow_tbl_deferred_destroy(old_table);
+                       }
+               }
+       }
+       rtnl_unlock();
+       genl_unlock();
+
+       schedule_delayed_work(&rehash_flow_wq, REHASH_FLOW_INTERVAL);
+}
+
+static int __net_init ovs_init_net(struct net *net)
+{
+       struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
+
+       INIT_LIST_HEAD(&ovs_net->dps);
+       return 0;
+}
+
+static void __net_exit ovs_exit_net(struct net *net)
+{
+       struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
+       struct datapath *dp, *dp_next;
+
+       genl_lock();
+       list_for_each_entry_safe(dp, dp_next, &ovs_net->dps, list_node)
+               __dp_destroy(dp);
+       genl_unlock();
+}
+
+static struct pernet_operations ovs_net_ops = {
+       .init = ovs_init_net,
+       .exit = ovs_exit_net,
+       .id   = &ovs_net_id,
+       .size = sizeof(struct ovs_net),
+};
+
 static int __init dp_init(void)
 {
        struct sk_buff *dummy_skb;
@@ -1889,10 +1981,14 @@ static int __init dp_init(void)
        if (err)
                goto error_flow_exit;
 
-       err = register_netdevice_notifier(&ovs_dp_device_notifier);
+       err = register_pernet_device(&ovs_net_ops);
        if (err)
                goto error_vport_exit;
 
+       err = register_netdevice_notifier(&ovs_dp_device_notifier);
+       if (err)
+               goto error_netns_exit;
+
        err = dp_register_genl();
        if (err < 0)
                goto error_unreg_notifier;
@@ -1903,6 +1999,8 @@ static int __init dp_init(void)
 
 error_unreg_notifier:
        unregister_netdevice_notifier(&ovs_dp_device_notifier);
+error_netns_exit:
+       unregister_pernet_device(&ovs_net_ops);
 error_vport_exit:
        ovs_vport_exit();
 error_flow_exit:
@@ -1914,9 +2012,10 @@ error:
 static void dp_cleanup(void)
 {
        cancel_delayed_work_sync(&rehash_flow_wq);
-       rcu_barrier();
        dp_unregister_genl(ARRAY_SIZE(dp_genl_families));
        unregister_netdevice_notifier(&ovs_dp_device_notifier);
+       unregister_pernet_device(&ovs_net_ops);
+       rcu_barrier();
        ovs_vport_exit();
        ovs_flow_exit();
 }
index c1105c147531001b65e8cdf75b0ccab2558bae0e..031dfbf37c937dff57657d33d45143d454cc4e46 100644 (file)
 #include <linux/u64_stats_sync.h>
 
 #include "flow.h"
+#include "vport.h"
 
-struct vport;
+#define DP_MAX_PORTS           USHRT_MAX
+#define DP_VPORT_HASH_BUCKETS  1024
 
-#define DP_MAX_PORTS 1024
 #define SAMPLE_ACTION_DEPTH 3
 
 /**
@@ -58,11 +59,10 @@ struct dp_stats_percpu {
  * @list_node: Element in global 'dps' list.
  * @n_flows: Number of flows currently in flow table.
  * @table: Current flow table.  Protected by genl_lock and RCU.
- * @ports: Map from port number to &struct vport.  %OVSP_LOCAL port
- * always exists, other ports may be %NULL.  Protected by RTNL and RCU.
- * @port_list: List of all ports in @ports in arbitrary order.  RTNL required
- * to iterate or modify.
+ * @ports: Hash table for ports.  %OVSP_LOCAL port always exists.  Protected by
+ * RTNL and RCU.
  * @stats_percpu: Per-CPU datapath statistics.
+ * @net: Reference to net namespace.
  *
  * Context: See the comment on locking at the top of datapath.c for additional
  * locking information.
@@ -75,13 +75,37 @@ struct datapath {
        struct flow_table __rcu *table;
 
        /* Switch ports. */
-       struct vport __rcu *ports[DP_MAX_PORTS];
-       struct list_head port_list;
+       struct hlist_head *ports;
 
        /* Stats. */
        struct dp_stats_percpu __percpu *stats_percpu;
+
+#ifdef CONFIG_NET_NS
+       /* Network namespace ref. */
+       struct net *net;
+#endif
 };
 
+struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no);
+
+static inline struct vport *ovs_vport_rcu(const struct datapath *dp, int port_no)
+{
+       WARN_ON_ONCE(!rcu_read_lock_held());
+       return ovs_lookup_vport(dp, port_no);
+}
+
+static inline struct vport *ovs_vport_rtnl_rcu(const struct datapath *dp, int port_no)
+{
+       WARN_ON_ONCE(!rcu_read_lock_held() && !rtnl_is_locked());
+       return ovs_lookup_vport(dp, port_no);
+}
+
+static inline struct vport *ovs_vport_rtnl(const struct datapath *dp, int port_no)
+{
+       ASSERT_RTNL();
+       return ovs_lookup_vport(dp, port_no);
+}
+
 /**
  * struct ovs_skb_cb - OVS data in skb CB
  * @flow: The flow associated with this packet.  May be %NULL if no flow.
@@ -105,9 +129,19 @@ struct dp_upcall_info {
        u8 cmd;
        const struct sw_flow_key *key;
        const struct nlattr *userdata;
-       u32 pid;
+       u32 portid;
 };
 
+static inline struct net *ovs_dp_get_net(struct datapath *dp)
+{
+       return read_pnet(&dp->net);
+}
+
+static inline void ovs_dp_set_net(struct datapath *dp, struct net *net)
+{
+       write_pnet(&dp->net, net);
+}
+
 extern struct notifier_block ovs_dp_device_notifier;
 extern struct genl_multicast_group ovs_dp_vport_multicast_group;
 
index 36dcee8fc84a27dc29785e9a1adfecb8f021ee57..5558350e0d33ee4f9b26f8be13801a6139fb7aa8 100644 (file)
@@ -41,19 +41,21 @@ static int dp_device_event(struct notifier_block *unused, unsigned long event,
        case NETDEV_UNREGISTER:
                if (!ovs_is_internal_dev(dev)) {
                        struct sk_buff *notify;
+                       struct datapath *dp = vport->dp;
 
                        notify = ovs_vport_cmd_build_info(vport, 0, 0,
                                                          OVS_VPORT_CMD_DEL);
                        ovs_dp_detach_port(vport);
                        if (IS_ERR(notify)) {
-                               netlink_set_err(init_net.genl_sock, 0,
+                               netlink_set_err(ovs_dp_get_net(dp)->genl_sock, 0,
                                                ovs_dp_vport_multicast_group.id,
                                                PTR_ERR(notify));
                                break;
                        }
 
-                       genlmsg_multicast(notify, 0, ovs_dp_vport_multicast_group.id,
-                                         GFP_KERNEL);
+                       genlmsg_multicast_netns(ovs_dp_get_net(dp), notify, 0,
+                                               ovs_dp_vport_multicast_group.id,
+                                               GFP_KERNEL);
                }
                break;
        }
index c7bf2f26525ad5cf87de88b1a9998ae4c2cfaf3d..98c70630ad06178778dc4f1e04275fa6032facc8 100644 (file)
@@ -203,10 +203,7 @@ struct sw_flow_actions *ovs_flow_actions_alloc(const struct nlattr *actions)
        int actions_len = nla_len(actions);
        struct sw_flow_actions *sfa;
 
-       /* At least DP_MAX_PORTS actions are required to be able to flood a
-        * packet to every port.  Factor of 2 allows for setting VLAN tags,
-        * etc. */
-       if (actions_len > 2 * DP_MAX_PORTS * nla_total_size(4))
+       if (actions_len > MAX_ACTIONS_BUFSIZE)
                return ERR_PTR(-EINVAL);
 
        sfa = kmalloc(sizeof(*sfa) + actions_len, GFP_KERNEL);
@@ -992,7 +989,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
                swkey->phy.in_port = in_port;
                attrs &= ~(1 << OVS_KEY_ATTR_IN_PORT);
        } else {
-               swkey->phy.in_port = USHRT_MAX;
+               swkey->phy.in_port = DP_MAX_PORTS;
        }
 
        /* Data attributes. */
@@ -1135,7 +1132,7 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
        const struct nlattr *nla;
        int rem;
 
-       *in_port = USHRT_MAX;
+       *in_port = DP_MAX_PORTS;
        *priority = 0;
 
        nla_for_each_nested(nla, attr, rem) {
@@ -1172,7 +1169,7 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
            nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority))
                goto nla_put_failure;
 
-       if (swkey->phy.in_port != USHRT_MAX &&
+       if (swkey->phy.in_port != DP_MAX_PORTS &&
            nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port))
                goto nla_put_failure;
 
index 9b75617ca4e031db60ddbeb609bb658af7f8de0c..d92e22a638cfdf273f1d9199669304c28a02da30 100644 (file)
@@ -43,7 +43,7 @@ struct sw_flow_actions {
 struct sw_flow_key {
        struct {
                u32     priority;       /* Packet QoS priority. */
-               u16     in_port;        /* Input switch port (or USHRT_MAX). */
+               u16     in_port;        /* Input switch port (or DP_MAX_PORTS). */
        } phy;
        struct {
                u8     src[ETH_ALEN];   /* Ethernet source address. */
@@ -161,6 +161,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
 int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
                               const struct nlattr *);
 
+#define MAX_ACTIONS_BUFSIZE    (16 * 1024)
 #define TBL_MIN_BUCKETS                1024
 
 struct flow_table {
index 4061b9ee07f7ca30af27ffa6f4264716dcda4e84..5d460c37df07ce70b615de1cff8e2191e358bab1 100644 (file)
@@ -144,7 +144,7 @@ static void do_setup(struct net_device *netdev)
        netdev->tx_queue_len = 0;
 
        netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_FRAGLIST |
-                               NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_TSO;
+                          NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_TSO;
 
        netdev->vlan_features = netdev->features;
        netdev->features |= NETIF_F_HW_VLAN_TX;
@@ -175,9 +175,14 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
                goto error_free_vport;
        }
 
+       dev_net_set(netdev_vport->dev, ovs_dp_get_net(vport->dp));
        internal_dev = internal_dev_priv(netdev_vport->dev);
        internal_dev->vport = vport;
 
+       /* Restrict bridge port to current netns. */
+       if (vport->port_no == OVSP_LOCAL)
+               netdev_vport->dev->features |= NETIF_F_NETNS_LOCAL;
+
        err = register_netdevice(netdev_vport->dev);
        if (err)
                goto error_free_netdev;
index 6ea3551cc78c8f21a966aeaeffc04a575eeeb824..3c1e58ba714bf9534b597c9f28147cc7c3038b39 100644 (file)
@@ -83,7 +83,7 @@ static struct vport *netdev_create(const struct vport_parms *parms)
 
        netdev_vport = netdev_vport_priv(vport);
 
-       netdev_vport->dev = dev_get_by_name(&init_net, parms->name);
+       netdev_vport->dev = dev_get_by_name(ovs_dp_get_net(vport->dp), parms->name);
        if (!netdev_vport->dev) {
                err = -ENODEV;
                goto error_free_vport;
index 6140336e79d7dd679603b7a1cb7dc750d3ed7f10..9055dd698c70bc78c7f53728ac7f8611d937b338 100644 (file)
  * 02110-1301, USA
  */
 
-#include <linux/dcache.h>
 #include <linux/etherdevice.h>
 #include <linux/if.h>
 #include <linux/if_vlan.h>
+#include <linux/jhash.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
@@ -27,7 +27,9 @@
 #include <linux/rcupdate.h>
 #include <linux/rtnetlink.h>
 #include <linux/compat.h>
+#include <net/net_namespace.h>
 
+#include "datapath.h"
 #include "vport.h"
 #include "vport-internal_dev.h"
 
@@ -67,9 +69,9 @@ void ovs_vport_exit(void)
        kfree(dev_table);
 }
 
-static struct hlist_head *hash_bucket(const char *name)
+static struct hlist_head *hash_bucket(struct net *net, const char *name)
 {
-       unsigned int hash = full_name_hash(name, strlen(name));
+       unsigned int hash = jhash(name, strlen(name), (unsigned long) net);
        return &dev_table[hash & (VPORT_HASH_BUCKETS - 1)];
 }
 
@@ -80,14 +82,15 @@ static struct hlist_head *hash_bucket(const char *name)
  *
  * Must be called with RTNL or RCU read lock.
  */
-struct vport *ovs_vport_locate(const char *name)
+struct vport *ovs_vport_locate(struct net *net, const char *name)
 {
-       struct hlist_head *bucket = hash_bucket(name);
+       struct hlist_head *bucket = hash_bucket(net, name);
        struct vport *vport;
        struct hlist_node *node;
 
        hlist_for_each_entry_rcu(vport, node, bucket, hash_node)
-               if (!strcmp(name, vport->ops->get_name(vport)))
+               if (!strcmp(name, vport->ops->get_name(vport)) &&
+                   net_eq(ovs_dp_get_net(vport->dp), net))
                        return vport;
 
        return NULL;
@@ -122,8 +125,9 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,
 
        vport->dp = parms->dp;
        vport->port_no = parms->port_no;
-       vport->upcall_pid = parms->upcall_pid;
+       vport->upcall_portid = parms->upcall_portid;
        vport->ops = ops;
+       INIT_HLIST_NODE(&vport->dp_hash_node);
 
        vport->percpu_stats = alloc_percpu(struct vport_percpu_stats);
        if (!vport->percpu_stats) {
@@ -170,14 +174,17 @@ struct vport *ovs_vport_add(const struct vport_parms *parms)
 
        for (i = 0; i < ARRAY_SIZE(vport_ops_list); i++) {
                if (vport_ops_list[i]->type == parms->type) {
+                       struct hlist_head *bucket;
+
                        vport = vport_ops_list[i]->create(parms);
                        if (IS_ERR(vport)) {
                                err = PTR_ERR(vport);
                                goto out;
                        }
 
-                       hlist_add_head_rcu(&vport->hash_node,
-                                          hash_bucket(vport->ops->get_name(vport)));
+                       bucket = hash_bucket(ovs_dp_get_net(vport->dp),
+                                            vport->ops->get_name(vport));
+                       hlist_add_head_rcu(&vport->hash_node, bucket);
                        return vport;
                }
        }
index aac680ca2b06410ec3300766583c3aaef78370ca..3f7961ea3c568d54011d6a570975fceb3c20d15f 100644 (file)
@@ -20,6 +20,7 @@
 #define VPORT_H 1
 
 #include <linux/list.h>
+#include <linux/netlink.h>
 #include <linux/openvswitch.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
@@ -38,7 +39,7 @@ void ovs_vport_exit(void);
 struct vport *ovs_vport_add(const struct vport_parms *);
 void ovs_vport_del(struct vport *);
 
-struct vport *ovs_vport_locate(const char *name);
+struct vport *ovs_vport_locate(struct net *net, const char *name);
 
 void ovs_vport_get_stats(struct vport *, struct ovs_vport_stats *);
 
@@ -69,10 +70,10 @@ struct vport_err_stats {
  * @rcu: RCU callback head for deferred destruction.
  * @port_no: Index into @dp's @ports array.
  * @dp: Datapath to which this port belongs.
- * @node: Element in @dp's @port_list.
- * @upcall_pid: The Netlink port to use for packets received on this port that
+ * @upcall_portid: The Netlink port to use for packets received on this port that
  * miss the flow table.
  * @hash_node: Element in @dev_table hash table in vport.c.
+ * @dp_hash_node: Element in @datapath->ports hash table in datapath.c.
  * @ops: Class structure.
  * @percpu_stats: Points to per-CPU statistics used and maintained by vport
  * @stats_lock: Protects @err_stats;
@@ -82,10 +83,10 @@ struct vport {
        struct rcu_head rcu;
        u16 port_no;
        struct datapath *dp;
-       struct list_head node;
-       u32 upcall_pid;
+       u32 upcall_portid;
 
        struct hlist_node hash_node;
+       struct hlist_node dp_hash_node;
        const struct vport_ops *ops;
 
        struct vport_percpu_stats __percpu *percpu_stats;
@@ -112,7 +113,7 @@ struct vport_parms {
        /* For ovs_vport_alloc(). */
        struct datapath *dp;
        u16 port_no;
-       u32 upcall_pid;
+       u32 upcall_portid;
 };
 
 /**
index 39bce0d50df9265ffc1c3f93846d4b194c5e6660..8db6e21c46bd619f6bc2c271a41d27b70772112e 100644 (file)
@@ -126,13 +126,13 @@ static int pdiag_put_fanout(struct packet_sock *po, struct sk_buff *nlskb)
 }
 
 static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag_req *req,
-               u32 pid, u32 seq, u32 flags, int sk_ino)
+               u32 portid, u32 seq, u32 flags, int sk_ino)
 {
        struct nlmsghdr *nlh;
        struct packet_diag_msg *rp;
        struct packet_sock *po = pkt_sk(sk);
 
-       nlh = nlmsg_put(skb, pid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rp), flags);
+       nlh = nlmsg_put(skb, portid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rp), flags);
        if (!nlh)
                return -EMSGSIZE;
 
@@ -184,7 +184,7 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
                if (num < s_num)
                        goto next;
 
-               if (sk_diag_fill(sk, skb, req, NETLINK_CB(cb->skb).pid,
+               if (sk_diag_fill(sk, skb, req, NETLINK_CB(cb->skb).portid,
                                        cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                        sock_i_ino(sk)) < 0)
                        goto done;
index 7dd762a464e55f9ef7f41c83b433aa81b6f4d7cf..83a8389619aa7ccc0a490a8f8b664200bee53df9 100644 (file)
@@ -33,7 +33,7 @@
 /* Device address handling */
 
 static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr,
-                    u32 pid, u32 seq, int event);
+                    u32 portid, u32 seq, int event);
 
 void phonet_address_notify(int event, struct net_device *dev, u8 addr)
 {
@@ -101,12 +101,12 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
 }
 
 static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr,
-                       u32 pid, u32 seq, int event)
+                       u32 portid, u32 seq, int event)
 {
        struct ifaddrmsg *ifm;
        struct nlmsghdr *nlh;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), 0);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*ifm), 0);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -148,7 +148,7 @@ static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
                                continue;
 
                        if (fill_addr(skb, pnd->netdev, addr << 2,
-                                        NETLINK_CB(cb->skb).pid,
+                                        NETLINK_CB(cb->skb).portid,
                                        cb->nlh->nlmsg_seq, RTM_NEWADDR) < 0)
                                goto out;
                }
@@ -165,12 +165,12 @@ out:
 /* Routes handling */
 
 static int fill_route(struct sk_buff *skb, struct net_device *dev, u8 dst,
-                       u32 pid, u32 seq, int event)
+                       u32 portid, u32 seq, int event)
 {
        struct rtmsg *rtm;
        struct nlmsghdr *nlh;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), 0);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*rtm), 0);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -276,7 +276,7 @@ static int route_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
 
                if (addr_idx++ < addr_start_idx)
                        continue;
-               if (fill_route(skb, dev, addr << 2, NETLINK_CB(cb->skb).pid,
+               if (fill_route(skb, dev, addr << 2, NETLINK_CB(cb->skb).portid,
                                cb->nlh->nlmsg_seq, RTM_NEWROUTE))
                        goto out;
        }
index e3d2c78cb52c9aebf735fa01c1712203216a920e..102761d294cbe7b470de479be5f07b7c5d4d69ed 100644 (file)
@@ -644,7 +644,7 @@ errout:
 }
 
 static int
-tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
+tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 portid, u32 seq,
             u16 flags, int event, int bind, int ref)
 {
        struct tcamsg *t;
@@ -652,7 +652,7 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
        unsigned char *b = skb_tail_pointer(skb);
        struct nlattr *nest;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*t), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*t), flags);
        if (!nlh)
                goto out_nlmsg_trim;
        t = nlmsg_data(nlh);
@@ -678,7 +678,7 @@ out_nlmsg_trim:
 }
 
 static int
-act_get_notify(struct net *net, u32 pid, struct nlmsghdr *n,
+act_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
               struct tc_action *a, int event)
 {
        struct sk_buff *skb;
@@ -686,16 +686,16 @@ act_get_notify(struct net *net, u32 pid, struct nlmsghdr *n,
        skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
        if (!skb)
                return -ENOBUFS;
-       if (tca_get_fill(skb, a, pid, n->nlmsg_seq, 0, event, 0, 0) <= 0) {
+       if (tca_get_fill(skb, a, portid, n->nlmsg_seq, 0, event, 0, 0) <= 0) {
                kfree_skb(skb);
                return -EINVAL;
        }
 
-       return rtnl_unicast(skb, net, pid);
+       return rtnl_unicast(skb, net, portid);
 }
 
 static struct tc_action *
-tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
+tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid)
 {
        struct nlattr *tb[TCA_ACT_MAX + 1];
        struct tc_action *a;
@@ -762,7 +762,7 @@ static struct tc_action *create_a(int i)
 }
 
 static int tca_action_flush(struct net *net, struct nlattr *nla,
-                           struct nlmsghdr *n, u32 pid)
+                           struct nlmsghdr *n, u32 portid)
 {
        struct sk_buff *skb;
        unsigned char *b;
@@ -799,7 +799,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
        if (a->ops == NULL)
                goto err_out;
 
-       nlh = nlmsg_put(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t), 0);
+       nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t), 0);
        if (!nlh)
                goto out_module_put;
        t = nlmsg_data(nlh);
@@ -823,7 +823,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
        nlh->nlmsg_flags |= NLM_F_ROOT;
        module_put(a->ops->owner);
        kfree(a);
-       err = rtnetlink_send(skb, net, pid, RTNLGRP_TC,
+       err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
                             n->nlmsg_flags & NLM_F_ECHO);
        if (err > 0)
                return 0;
@@ -841,7 +841,7 @@ noflush_out:
 
 static int
 tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
-             u32 pid, int event)
+             u32 portid, int event)
 {
        int i, ret;
        struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
@@ -853,13 +853,13 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
 
        if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) {
                if (tb[1] != NULL)
-                       return tca_action_flush(net, tb[1], n, pid);
+                       return tca_action_flush(net, tb[1], n, portid);
                else
                        return -EINVAL;
        }
 
        for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
-               act = tcf_action_get_1(tb[i], n, pid);
+               act = tcf_action_get_1(tb[i], n, portid);
                if (IS_ERR(act)) {
                        ret = PTR_ERR(act);
                        goto err;
@@ -874,7 +874,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
        }
 
        if (event == RTM_GETACTION)
-               ret = act_get_notify(net, pid, n, head, event);
+               ret = act_get_notify(net, portid, n, head, event);
        else { /* delete */
                struct sk_buff *skb;
 
@@ -884,7 +884,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
                        goto err;
                }
 
-               if (tca_get_fill(skb, head, pid, n->nlmsg_seq, 0, event,
+               if (tca_get_fill(skb, head, portid, n->nlmsg_seq, 0, event,
                                 0, 1) <= 0) {
                        kfree_skb(skb);
                        ret = -EINVAL;
@@ -893,7 +893,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
 
                /* now do the delete */
                tcf_action_destroy(head, 0);
-               ret = rtnetlink_send(skb, net, pid, RTNLGRP_TC,
+               ret = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
                                     n->nlmsg_flags & NLM_F_ECHO);
                if (ret > 0)
                        return 0;
@@ -905,7 +905,7 @@ err:
 }
 
 static int tcf_add_notify(struct net *net, struct tc_action *a,
-                         u32 pid, u32 seq, int event, u16 flags)
+                         u32 portid, u32 seq, int event, u16 flags)
 {
        struct tcamsg *t;
        struct nlmsghdr *nlh;
@@ -920,7 +920,7 @@ static int tcf_add_notify(struct net *net, struct tc_action *a,
 
        b = skb_tail_pointer(skb);
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*t), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*t), flags);
        if (!nlh)
                goto out_kfree_skb;
        t = nlmsg_data(nlh);
@@ -940,7 +940,7 @@ static int tcf_add_notify(struct net *net, struct tc_action *a,
        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
        NETLINK_CB(skb).dst_group = RTNLGRP_TC;
 
-       err = rtnetlink_send(skb, net, pid, RTNLGRP_TC, flags & NLM_F_ECHO);
+       err = rtnetlink_send(skb, net, portid, RTNLGRP_TC, flags & NLM_F_ECHO);
        if (err > 0)
                err = 0;
        return err;
@@ -953,7 +953,7 @@ out_kfree_skb:
 
 static int
 tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
-              u32 pid, int ovr)
+              u32 portid, int ovr)
 {
        int ret = 0;
        struct tc_action *act;
@@ -971,7 +971,7 @@ tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
        /* dump then free all the actions after update; inserted policy
         * stays intact
         */
-       ret = tcf_add_notify(net, act, pid, seq, RTM_NEWACTION, n->nlmsg_flags);
+       ret = tcf_add_notify(net, act, portid, seq, RTM_NEWACTION, n->nlmsg_flags);
        for (a = act; a; a = act) {
                act = a->next;
                kfree(a);
@@ -984,7 +984,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 {
        struct net *net = sock_net(skb->sk);
        struct nlattr *tca[TCA_ACT_MAX + 1];
-       u32 pid = skb ? NETLINK_CB(skb).pid : 0;
+       u32 portid = skb ? NETLINK_CB(skb).portid : 0;
        int ret = 0, ovr = 0;
 
        ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL);
@@ -1008,17 +1008,17 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
                if (n->nlmsg_flags & NLM_F_REPLACE)
                        ovr = 1;
 replay:
-               ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, pid, ovr);
+               ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr);
                if (ret == -EAGAIN)
                        goto replay;
                break;
        case RTM_DELACTION:
                ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
-                                   pid, RTM_DELACTION);
+                                   portid, RTM_DELACTION);
                break;
        case RTM_GETACTION:
                ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
-                                   pid, RTM_GETACTION);
+                                   portid, RTM_GETACTION);
                break;
        default:
                BUG();
@@ -1085,7 +1085,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
                goto out_module_put;
        }
 
-       nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
+       nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
                        cb->nlh->nlmsg_type, sizeof(*t), 0);
        if (!nlh)
                goto out_module_put;
@@ -1109,7 +1109,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
                nla_nest_cancel(skb, nest);
 
        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
-       if (NETLINK_CB(cb->skb).pid && ret)
+       if (NETLINK_CB(cb->skb).portid && ret)
                nlh->nlmsg_flags |= NLM_F_MULTI;
        module_put(a_o->owner);
        return skb->len;
index dc3ef5aef3559a4e4dd0f490230789e0e440e8f3..7ae02892437c25bf1e925d6dc756ed23aabff1a3 100644 (file)
@@ -343,13 +343,13 @@ errout:
 }
 
 static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp,
-                        unsigned long fh, u32 pid, u32 seq, u16 flags, int event)
+                        unsigned long fh, u32 portid, u32 seq, u16 flags, int event)
 {
        struct tcmsg *tcm;
        struct nlmsghdr  *nlh;
        unsigned char *b = skb_tail_pointer(skb);
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*tcm), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags);
        if (!nlh)
                goto out_nlmsg_trim;
        tcm = nlmsg_data(nlh);
@@ -381,18 +381,18 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb,
                          unsigned long fh, int event)
 {
        struct sk_buff *skb;
-       u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
+       u32 portid = oskb ? NETLINK_CB(oskb).portid : 0;
 
        skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
        if (!skb)
                return -ENOBUFS;
 
-       if (tcf_fill_node(skb, tp, fh, pid, n->nlmsg_seq, 0, event) <= 0) {
+       if (tcf_fill_node(skb, tp, fh, portid, n->nlmsg_seq, 0, event) <= 0) {
                kfree_skb(skb);
                return -EINVAL;
        }
 
-       return rtnetlink_send(skb, net, pid, RTNLGRP_TC,
+       return rtnetlink_send(skb, net, portid, RTNLGRP_TC,
                              n->nlmsg_flags & NLM_F_ECHO);
 }
 
@@ -407,7 +407,7 @@ static int tcf_node_dump(struct tcf_proto *tp, unsigned long n,
 {
        struct tcf_dump_args *a = (void *)arg;
 
-       return tcf_fill_node(a->skb, tp, n, NETLINK_CB(a->cb->skb).pid,
+       return tcf_fill_node(a->skb, tp, n, NETLINK_CB(a->cb->skb).portid,
                             a->cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTFILTER);
 }
 
@@ -465,7 +465,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
                if (t > s_t)
                        memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0]));
                if (cb->args[1] == 0) {
-                       if (tcf_fill_node(skb, tp, 0, NETLINK_CB(cb->skb).pid,
+                       if (tcf_fill_node(skb, tp, 0, NETLINK_CB(cb->skb).portid,
                                          cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                          RTM_NEWTFILTER) <= 0)
                                break;
index a08b4ab3e421da67538f019cd6d7ec19f49fb12d..a18d975db59cea34eb0558490deb800f24c10d22 100644 (file)
@@ -1185,7 +1185,7 @@ graft:
 }
 
 static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
-                        u32 pid, u32 seq, u16 flags, int event)
+                        u32 portid, u32 seq, u16 flags, int event)
 {
        struct tcmsg *tcm;
        struct nlmsghdr  *nlh;
@@ -1193,7 +1193,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
        struct gnet_dump d;
        struct qdisc_size_table *stab;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*tcm), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags);
        if (!nlh)
                goto out_nlmsg_trim;
        tcm = nlmsg_data(nlh);
@@ -1248,25 +1248,25 @@ static int qdisc_notify(struct net *net, struct sk_buff *oskb,
                        struct Qdisc *old, struct Qdisc *new)
 {
        struct sk_buff *skb;
-       u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
+       u32 portid = oskb ? NETLINK_CB(oskb).portid : 0;
 
        skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
        if (!skb)
                return -ENOBUFS;
 
        if (old && !tc_qdisc_dump_ignore(old)) {
-               if (tc_fill_qdisc(skb, old, clid, pid, n->nlmsg_seq,
+               if (tc_fill_qdisc(skb, old, clid, portid, n->nlmsg_seq,
                                  0, RTM_DELQDISC) < 0)
                        goto err_out;
        }
        if (new && !tc_qdisc_dump_ignore(new)) {
-               if (tc_fill_qdisc(skb, new, clid, pid, n->nlmsg_seq,
+               if (tc_fill_qdisc(skb, new, clid, portid, n->nlmsg_seq,
                                  old ? NLM_F_REPLACE : 0, RTM_NEWQDISC) < 0)
                        goto err_out;
        }
 
        if (skb->len)
-               return rtnetlink_send(skb, net, pid, RTNLGRP_TC,
+               return rtnetlink_send(skb, net, portid, RTNLGRP_TC,
                                      n->nlmsg_flags & NLM_F_ECHO);
 
 err_out:
@@ -1289,7 +1289,7 @@ static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
                q_idx++;
        } else {
                if (!tc_qdisc_dump_ignore(q) &&
-                   tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid,
+                   tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).portid,
                                  cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0)
                        goto done;
                q_idx++;
@@ -1300,7 +1300,7 @@ static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
                        continue;
                }
                if (!tc_qdisc_dump_ignore(q) &&
-                   tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid,
+                   tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).portid,
                                  cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0)
                        goto done;
                q_idx++;
@@ -1375,7 +1375,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
        const struct Qdisc_class_ops *cops;
        unsigned long cl = 0;
        unsigned long new_cl;
-       u32 pid = tcm->tcm_parent;
+       u32 portid = tcm->tcm_parent;
        u32 clid = tcm->tcm_handle;
        u32 qid = TC_H_MAJ(clid);
        int err;
@@ -1403,8 +1403,8 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 
        /* Step 1. Determine qdisc handle X:0 */
 
-       if (pid != TC_H_ROOT) {
-               u32 qid1 = TC_H_MAJ(pid);
+       if (portid != TC_H_ROOT) {
+               u32 qid1 = TC_H_MAJ(portid);
 
                if (qid && qid1) {
                        /* If both majors are known, they must be identical. */
@@ -1418,10 +1418,10 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
                /* Now qid is genuine qdisc handle consistent
                 * both with parent and child.
                 *
-                * TC_H_MAJ(pid) still may be unspecified, complete it now.
+                * TC_H_MAJ(portid) still may be unspecified, complete it now.
                 */
-               if (pid)
-                       pid = TC_H_MAKE(qid, pid);
+               if (portid)
+                       portid = TC_H_MAKE(qid, portid);
        } else {
                if (qid == 0)
                        qid = dev->qdisc->handle;
@@ -1439,7 +1439,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 
        /* Now try to get class */
        if (clid == 0) {
-               if (pid == TC_H_ROOT)
+               if (portid == TC_H_ROOT)
                        clid = qid;
        } else
                clid = TC_H_MAKE(qid, clid);
@@ -1478,7 +1478,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
        new_cl = cl;
        err = -EOPNOTSUPP;
        if (cops->change)
-               err = cops->change(q, clid, pid, tca, &new_cl);
+               err = cops->change(q, clid, portid, tca, &new_cl);
        if (err == 0)
                tclass_notify(net, skb, n, q, new_cl, RTM_NEWTCLASS);
 
@@ -1492,7 +1492,7 @@ out:
 
 static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
                          unsigned long cl,
-                         u32 pid, u32 seq, u16 flags, int event)
+                         u32 portid, u32 seq, u16 flags, int event)
 {
        struct tcmsg *tcm;
        struct nlmsghdr  *nlh;
@@ -1500,7 +1500,7 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
        struct gnet_dump d;
        const struct Qdisc_class_ops *cl_ops = q->ops->cl_ops;
 
-       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*tcm), flags);
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags);
        if (!nlh)
                goto out_nlmsg_trim;
        tcm = nlmsg_data(nlh);
@@ -1540,18 +1540,18 @@ static int tclass_notify(struct net *net, struct sk_buff *oskb,
                         unsigned long cl, int event)
 {
        struct sk_buff *skb;
-       u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
+       u32 portid = oskb ? NETLINK_CB(oskb).portid : 0;
 
        skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
        if (!skb)
                return -ENOBUFS;
 
-       if (tc_fill_tclass(skb, q, cl, pid, n->nlmsg_seq, 0, event) < 0) {
+       if (tc_fill_tclass(skb, q, cl, portid, n->nlmsg_seq, 0, event) < 0) {
                kfree_skb(skb);
                return -EINVAL;
        }
 
-       return rtnetlink_send(skb, net, pid, RTNLGRP_TC,
+       return rtnetlink_send(skb, net, portid, RTNLGRP_TC,
                              n->nlmsg_flags & NLM_F_ECHO);
 }
 
@@ -1565,7 +1565,7 @@ static int qdisc_class_dump(struct Qdisc *q, unsigned long cl, struct qdisc_walk
 {
        struct qdisc_dump_args *a = (struct qdisc_dump_args *)arg;
 
-       return tc_fill_tclass(a->skb, q, cl, NETLINK_CB(a->cb->skb).pid,
+       return tc_fill_tclass(a->skb, q, cl, NETLINK_CB(a->cb->skb).portid,
                              a->cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTCLASS);
 }
 
index 6c4d5fe53ce80ab534b34431f246a0ec4b48e055..aefc1504dc88f8b07963c390417f6dbf26544fa5 100644 (file)
@@ -527,6 +527,8 @@ struct Qdisc_ops pfifo_fast_ops __read_mostly = {
 };
 EXPORT_SYMBOL(pfifo_fast_ops);
 
+static struct lock_class_key qdisc_tx_busylock;
+
 struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
                          struct Qdisc_ops *ops)
 {
@@ -534,6 +536,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
        struct Qdisc *sch;
        unsigned int size = QDISC_ALIGN(sizeof(*sch)) + ops->priv_size;
        int err = -ENOBUFS;
+       struct net_device *dev = dev_queue->dev;
 
        p = kzalloc_node(size, GFP_KERNEL,
                         netdev_queue_numa_node_read(dev_queue));
@@ -553,12 +556,16 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
        }
        INIT_LIST_HEAD(&sch->list);
        skb_queue_head_init(&sch->q);
+
        spin_lock_init(&sch->busylock);
+       lockdep_set_class(&sch->busylock,
+                         dev->qdisc_tx_busylock ?: &qdisc_tx_busylock);
+
        sch->ops = ops;
        sch->enqueue = ops->enqueue;
        sch->dequeue = ops->dequeue;
        sch->dev_queue = dev_queue;
-       dev_hold(qdisc_dev(sch));
+       dev_hold(dev);
        atomic_set(&sch->refcnt, 1);
 
        return sch;
index 072bf6ae3c26da20baa92d07b9c6248b86db95b2..d16632e1503a56a4c592157936ab568a2be3a3a4 100644 (file)
@@ -591,9 +591,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
                 * next chunk.
                 */
                if (chunk->tsn_gap_acked) {
-                       list_del(&chunk->transmitted_list);
-                       list_add_tail(&chunk->transmitted_list,
-                                       &transport->transmitted);
+                       list_move_tail(&chunk->transmitted_list,
+                                      &transport->transmitted);
                        continue;
                }
 
@@ -657,9 +656,8 @@ redo:
                        /* The append was successful, so add this chunk to
                         * the transmitted list.
                         */
-                       list_del(&chunk->transmitted_list);
-                       list_add_tail(&chunk->transmitted_list,
-                                       &transport->transmitted);
+                       list_move_tail(&chunk->transmitted_list,
+                                      &transport->transmitted);
 
                        /* Mark the chunk as ineligible for fast retransmit
                         * after it is retransmitted.
index a5471f804d994ece8c31df6be0e04d5076b6dfd0..977c0f48c8d6c3efa655a91a69f7911445b313a9 100644 (file)
@@ -88,6 +88,7 @@
 #include <linux/nsproxy.h>
 #include <linux/magic.h>
 #include <linux/slab.h>
+#include <linux/xattr.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -346,7 +347,8 @@ static struct file_system_type sock_fs_type = {
  *     but we take care of internal coherence yet.
  */
 
-static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
+static int sock_alloc_file(struct socket *sock, struct file **f, int flags,
+                          const char *dname)
 {
        struct qstr name = { .name = "" };
        struct path path;
@@ -357,6 +359,13 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
        if (unlikely(fd < 0))
                return fd;
 
+       if (dname) {
+               name.name = dname;
+               name.len = strlen(name.name);
+       } else if (sock->sk) {
+               name.name = sock->sk->sk_prot_creator->name;
+               name.len = strlen(name.name);
+       }
        path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name);
        if (unlikely(!path.dentry)) {
                put_unused_fd(fd);
@@ -389,7 +398,7 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
 int sock_map_fd(struct socket *sock, int flags)
 {
        struct file *newfile;
-       int fd = sock_alloc_file(sock, &newfile, flags);
+       int fd = sock_alloc_file(sock, &newfile, flags, NULL);
 
        if (likely(fd >= 0))
                fd_install(fd, newfile);
@@ -455,6 +464,68 @@ static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
        return NULL;
 }
 
+#define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname"
+#define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX)
+#define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1)
+static ssize_t sockfs_getxattr(struct dentry *dentry,
+                              const char *name, void *value, size_t size)
+{
+       const char *proto_name;
+       size_t proto_size;
+       int error;
+
+       error = -ENODATA;
+       if (!strncmp(name, XATTR_NAME_SOCKPROTONAME, XATTR_NAME_SOCKPROTONAME_LEN)) {
+               proto_name = dentry->d_name.name;
+               proto_size = strlen(proto_name);
+
+               if (value) {
+                       error = -ERANGE;
+                       if (proto_size + 1 > size)
+                               goto out;
+
+                       strncpy(value, proto_name, proto_size + 1);
+               }
+               error = proto_size + 1;
+       }
+
+out:
+       return error;
+}
+
+static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
+                               size_t size)
+{
+       ssize_t len;
+       ssize_t used = 0;
+
+       len = security_inode_listsecurity(dentry->d_inode, buffer, size);
+       if (len < 0)
+               return len;
+       used += len;
+       if (buffer) {
+               if (size < used)
+                       return -ERANGE;
+               buffer += len;
+       }
+
+       len = (XATTR_NAME_SOCKPROTONAME_LEN + 1);
+       used += len;
+       if (buffer) {
+               if (size < used)
+                       return -ERANGE;
+               memcpy(buffer, XATTR_NAME_SOCKPROTONAME, len);
+               buffer += len;
+       }
+
+       return used;
+}
+
+static const struct inode_operations sockfs_inode_ops = {
+       .getxattr = sockfs_getxattr,
+       .listxattr = sockfs_listxattr,
+};
+
 /**
  *     sock_alloc      -       allocate a socket
  *
@@ -479,6 +550,7 @@ static struct socket *sock_alloc(void)
        inode->i_mode = S_IFSOCK | S_IRWXUGO;
        inode->i_uid = current_fsuid();
        inode->i_gid = current_fsgid();
+       inode->i_op = &sockfs_inode_ops;
 
        this_cpu_add(sockets_in_use, 1);
        return sock;
@@ -1394,13 +1466,13 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
        if (err < 0)
                goto out_release_both;
 
-       fd1 = sock_alloc_file(sock1, &newfile1, flags);
+       fd1 = sock_alloc_file(sock1, &newfile1, flags, NULL);
        if (unlikely(fd1 < 0)) {
                err = fd1;
                goto out_release_both;
        }
 
-       fd2 = sock_alloc_file(sock2, &newfile2, flags);
+       fd2 = sock_alloc_file(sock2, &newfile2, flags, NULL);
        if (unlikely(fd2 < 0)) {
                err = fd2;
                fput(newfile1);
@@ -1536,7 +1608,8 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
         */
        __module_get(newsock->ops->owner);
 
-       newfd = sock_alloc_file(newsock, &newfile, flags);
+       newfd = sock_alloc_file(newsock, &newfile, flags,
+                               sock->sk->sk_prot_creator->name);
        if (unlikely(newfd < 0)) {
                err = newfd;
                sock_release(newsock);
index 47a839df27dc2387b0067ef38228872135860993..6675914dc592cd54b13e6320051f80296a7223c8 100644 (file)
@@ -62,7 +62,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
                rep_nlh = nlmsg_hdr(rep_buf);
                memcpy(rep_nlh, req_nlh, hdr_space);
                rep_nlh->nlmsg_len = rep_buf->len;
-               genlmsg_unicast(&init_net, rep_buf, NETLINK_CB(skb).pid);
+               genlmsg_unicast(&init_net, rep_buf, NETLINK_CB(skb).portid);
        }
 
        return 0;
index 750b13408449ac018b3d8ca1bad4def492ffaea6..06748f108a5732e9f847cdffd0dafe0cb996c191 100644 (file)
@@ -110,12 +110,12 @@ static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb)
 }
 
 static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
-               u32 pid, u32 seq, u32 flags, int sk_ino)
+               u32 portid, u32 seq, u32 flags, int sk_ino)
 {
        struct nlmsghdr *nlh;
        struct unix_diag_msg *rep;
 
-       nlh = nlmsg_put(skb, pid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rep),
+       nlh = nlmsg_put(skb, portid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rep),
                        flags);
        if (!nlh)
                return -EMSGSIZE;
@@ -159,7 +159,7 @@ out_nlmsg_trim:
 }
 
 static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
-               u32 pid, u32 seq, u32 flags)
+               u32 portid, u32 seq, u32 flags)
 {
        int sk_ino;
 
@@ -170,7 +170,7 @@ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, struct unix_diag_r
        if (!sk_ino)
                return 0;
 
-       return sk_diag_fill(sk, skb, req, pid, seq, flags, sk_ino);
+       return sk_diag_fill(sk, skb, req, portid, seq, flags, sk_ino);
 }
 
 static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
@@ -200,7 +200,7 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
                        if (!(req->udiag_states & (1 << sk->sk_state)))
                                goto next;
                        if (sk_diag_dump(sk, skb, req,
-                                        NETLINK_CB(cb->skb).pid,
+                                        NETLINK_CB(cb->skb).portid,
                                         cb->nlh->nlmsg_seq,
                                         NLM_F_MULTI) < 0)
                                goto done;
@@ -267,7 +267,7 @@ again:
        if (!rep)
                goto out;
 
-       err = sk_diag_fill(sk, rep, req, NETLINK_CB(in_skb).pid,
+       err = sk_diag_fill(sk, rep, req, NETLINK_CB(in_skb).portid,
                           nlh->nlmsg_seq, 0, req->udiag_ino);
        if (err < 0) {
                nlmsg_free(rep);
@@ -277,7 +277,7 @@ again:
 
                goto again;
        }
-       err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).pid,
+       err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid,
                              MSG_DONTWAIT);
        if (err > 0)
                err = 0;
index bc7430b54771af18e903ee1d263ede3b4eb1b78f..a343be4a52bd0e16b0fdb41e565f39f3d705c823 100644 (file)
@@ -55,7 +55,7 @@ struct cfg80211_registered_device {
        int opencount; /* also protected by devlist_mtx */
        wait_queue_head_t dev_wait;
 
-       u32 ap_beacons_nlpid;
+       u32 ap_beacons_nlportid;
 
        /* protected by RTNL only */
        int num_running_ifaces;
index 8fd0242ee1695a19c7755a7d0cd49343ac954a04..ec7fcee5bad65b2ed8a24de5a2d97d850926d882 100644 (file)
@@ -615,7 +615,7 @@ EXPORT_SYMBOL(cfg80211_del_sta);
 struct cfg80211_mgmt_registration {
        struct list_head list;
 
-       u32 nlpid;
+       u32 nlportid;
 
        int match_len;
 
@@ -624,7 +624,7 @@ struct cfg80211_mgmt_registration {
        u8 match[];
 };
 
-int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
+int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
                                u16 frame_type, const u8 *match_data,
                                int match_len)
 {
@@ -672,7 +672,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
 
        memcpy(nreg->match, match_data, match_len);
        nreg->match_len = match_len;
-       nreg->nlpid = snd_pid;
+       nreg->nlportid = snd_portid;
        nreg->frame_type = cpu_to_le16(frame_type);
        list_add(&nreg->list, &wdev->mgmt_registrations);
 
@@ -685,7 +685,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
        return err;
 }
 
-void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
+void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
 {
        struct wiphy *wiphy = wdev->wiphy;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
@@ -694,7 +694,7 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
        spin_lock_bh(&wdev->mgmt_registrations_lock);
 
        list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
-               if (reg->nlpid != nlpid)
+               if (reg->nlportid != nlportid)
                        continue;
 
                if (rdev->ops->mgmt_frame_register) {
@@ -710,8 +710,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
 
        spin_unlock_bh(&wdev->mgmt_registrations_lock);
 
-       if (nlpid == wdev->ap_unexpected_nlpid)
-               wdev->ap_unexpected_nlpid = 0;
+       if (nlportid == wdev->ap_unexpected_nlportid)
+               wdev->ap_unexpected_nlportid = 0;
 }
 
 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
@@ -872,7 +872,7 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
                /* found match! */
 
                /* Indicate the received Action frame to user space */
-               if (nl80211_send_mgmt(rdev, wdev, reg->nlpid,
+               if (nl80211_send_mgmt(rdev, wdev, reg->nlportid,
                                      freq, sig_mbm,
                                      buf, len, gfp))
                        continue;
index 787aeaa902fe6f00b68e2db59df05a08690fba81..34eb5c07a5679e7a365b90732b81232dce0ec2f2 100644 (file)
@@ -496,11 +496,11 @@ static bool is_valid_ie_attr(const struct nlattr *attr)
 }
 
 /* message building helper */
-static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
+static inline void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
                                   int flags, u8 cmd)
 {
        /* since there is no private header just add the generic one */
-       return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
+       return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
 }
 
 static int nl80211_msg_put_channel(struct sk_buff *msg,
@@ -851,7 +851,7 @@ nla_put_failure:
        return -ENOBUFS;
 }
 
-static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
+static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags,
                              struct cfg80211_registered_device *dev)
 {
        void *hdr;
@@ -866,7 +866,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
        const struct ieee80211_txrx_stypes *mgmt_stypes =
                                dev->wiphy.mgmt_stypes;
 
-       hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
+       hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY);
        if (!hdr)
                return -1;
 
@@ -1267,7 +1267,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
                        continue;
                if (++idx <= start)
                        continue;
-               if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
+               if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid,
                                       cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                       dev) < 0) {
                        idx--;
@@ -1290,7 +1290,7 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
        if (!msg)
                return -ENOMEM;
 
-       if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0) {
+       if (nl80211_send_wiphy(msg, info->snd_portid, info->snd_seq, 0, dev) < 0) {
                nlmsg_free(msg);
                return -ENOBUFS;
        }
@@ -1736,14 +1736,14 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
               ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32);
 }
 
-static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
+static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
                              struct cfg80211_registered_device *rdev,
                              struct wireless_dev *wdev)
 {
        struct net_device *dev = wdev->netdev;
        void *hdr;
 
-       hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE);
+       hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_INTERFACE);
        if (!hdr)
                return -1;
 
@@ -1807,7 +1807,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
                                if_idx++;
                                continue;
                        }
-                       if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
+                       if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
                                               cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                               rdev, wdev) < 0) {
                                mutex_unlock(&rdev->devlist_mtx);
@@ -1838,7 +1838,7 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
        if (!msg)
                return -ENOMEM;
 
-       if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0,
+       if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
                               dev, wdev) < 0) {
                nlmsg_free(msg);
                return -ENOBUFS;
@@ -2056,7 +2056,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
                break;
        }
 
-       if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0,
+       if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
                               rdev, wdev) < 0) {
                nlmsg_free(msg);
                return -ENOBUFS;
@@ -2191,7 +2191,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
        if (!msg)
                return -ENOMEM;
 
-       hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+       hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
                             NL80211_CMD_NEW_KEY);
        if (IS_ERR(hdr))
                return PTR_ERR(hdr);
@@ -2769,7 +2769,7 @@ nla_put_failure:
        return false;
 }
 
-static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
+static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
                                int flags,
                                struct cfg80211_registered_device *rdev,
                                struct net_device *dev,
@@ -2778,7 +2778,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
        void *hdr;
        struct nlattr *sinfoattr, *bss_param;
 
-       hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
+       hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION);
        if (!hdr)
                return -1;
 
@@ -2931,7 +2931,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
                        goto out_err;
 
                if (nl80211_send_station(skb,
-                               NETLINK_CB(cb->skb).pid,
+                               NETLINK_CB(cb->skb).portid,
                                cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                dev, netdev, mac_addr,
                                &sinfo) < 0)
@@ -2977,7 +2977,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
        if (!msg)
                return -ENOMEM;
 
-       if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
+       if (nl80211_send_station(msg, info->snd_portid, info->snd_seq, 0,
                                 rdev, dev, mac_addr, &sinfo) < 0) {
                nlmsg_free(msg);
                return -ENOBUFS;
@@ -3303,7 +3303,7 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
        return rdev->ops->del_station(&rdev->wiphy, dev, mac_addr);
 }
 
-static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
+static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
                                int flags, struct net_device *dev,
                                u8 *dst, u8 *next_hop,
                                struct mpath_info *pinfo)
@@ -3311,7 +3311,7 @@ static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
        void *hdr;
        struct nlattr *pinfoattr;
 
-       hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
+       hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION);
        if (!hdr)
                return -1;
 
@@ -3389,7 +3389,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
                if (err)
                        goto out_err;
 
-               if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid,
+               if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
                                       cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                       netdev, dst, next_hop,
                                       &pinfo) < 0)
@@ -3438,7 +3438,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
        if (!msg)
                return -ENOMEM;
 
-       if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0,
+       if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
                                 dev, dst, next_hop, &pinfo) < 0) {
                nlmsg_free(msg);
                return -ENOBUFS;
@@ -3679,7 +3679,7 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                return -ENOMEM;
-       hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+       hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
                             NL80211_CMD_GET_MESH_CONFIG);
        if (!hdr)
                goto out;
@@ -3998,7 +3998,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
                goto out;
        }
 
-       hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+       hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
                             NL80211_CMD_GET_REG);
        if (!hdr)
                goto put_failure;
@@ -4616,7 +4616,7 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
 
        ASSERT_WDEV_LOCK(wdev);
 
-       hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).pid, seq, flags,
+       hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
                             NL80211_CMD_NEW_SCAN_RESULTS);
        if (!hdr)
                return -1;
@@ -4735,14 +4735,14 @@ static int nl80211_dump_scan(struct sk_buff *skb,
        return skb->len;
 }
 
-static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
+static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
                                int flags, struct net_device *dev,
                                struct survey_info *survey)
 {
        void *hdr;
        struct nlattr *infoattr;
 
-       hdr = nl80211hdr_put(msg, pid, seq, flags,
+       hdr = nl80211hdr_put(msg, portid, seq, flags,
                             NL80211_CMD_NEW_SURVEY_RESULTS);
        if (!hdr)
                return -ENOMEM;
@@ -4836,7 +4836,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
                }
 
                if (nl80211_send_survey(skb,
-                               NETLINK_CB(cb->skb).pid,
+                               NETLINK_CB(cb->skb).portid,
                                cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                netdev,
                                &survey) < 0)
@@ -5451,7 +5451,7 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
        }
 
        while (1) {
-               void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).pid,
+               void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
                                           cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                           NL80211_CMD_TESTMODE);
                struct nlattr *tmdata;
@@ -5491,7 +5491,7 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
 
 static struct sk_buff *
 __cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev,
-                             int approxlen, u32 pid, u32 seq, gfp_t gfp)
+                             int approxlen, u32 portid, u32 seq, gfp_t gfp)
 {
        struct sk_buff *skb;
        void *hdr;
@@ -5501,7 +5501,7 @@ __cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev,
        if (!skb)
                return NULL;
 
-       hdr = nl80211hdr_put(skb, pid, seq, 0, NL80211_CMD_TESTMODE);
+       hdr = nl80211hdr_put(skb, portid, seq, 0, NL80211_CMD_TESTMODE);
        if (!hdr) {
                kfree_skb(skb);
                return NULL;
@@ -5531,7 +5531,7 @@ struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy,
                return NULL;
 
        return __cfg80211_testmode_alloc_skb(rdev, approxlen,
-                               rdev->testmode_info->snd_pid,
+                               rdev->testmode_info->snd_portid,
                                rdev->testmode_info->snd_seq,
                                GFP_KERNEL);
 }
@@ -5867,7 +5867,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
        if (!msg)
                return -ENOMEM;
 
-       hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+       hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
                             NL80211_CMD_REMAIN_ON_CHANNEL);
 
        if (IS_ERR(hdr)) {
@@ -6086,7 +6086,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
        if (!rdev->ops->mgmt_tx)
                return -EOPNOTSUPP;
 
-       return cfg80211_mlme_register_mgmt(wdev, info->snd_pid, frame_type,
+       return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
                        nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
                        nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
 }
@@ -6167,7 +6167,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
                if (!msg)
                        return -ENOMEM;
 
-               hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+               hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
                                     NL80211_CMD_FRAME);
 
                if (IS_ERR(hdr)) {
@@ -6284,7 +6284,7 @@ static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
        if (!msg)
                return -ENOMEM;
 
-       hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+       hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
                             NL80211_CMD_GET_POWER_SAVE);
        if (!hdr) {
                err = -ENOBUFS;
@@ -6486,7 +6486,7 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
        if (!msg)
                return -ENOMEM;
 
-       hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+       hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
                             NL80211_CMD_GET_WOWLAN);
        if (!hdr)
                goto nla_put_failure;
@@ -6760,10 +6760,10 @@ static int nl80211_register_unexpected_frame(struct sk_buff *skb,
            wdev->iftype != NL80211_IFTYPE_P2P_GO)
                return -EINVAL;
 
-       if (wdev->ap_unexpected_nlpid)
+       if (wdev->ap_unexpected_nlportid)
                return -EBUSY;
 
-       wdev->ap_unexpected_nlpid = info->snd_pid;
+       wdev->ap_unexpected_nlportid = info->snd_portid;
        return 0;
 }
 
@@ -6793,7 +6793,7 @@ static int nl80211_probe_client(struct sk_buff *skb,
        if (!msg)
                return -ENOMEM;
 
-       hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+       hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
                             NL80211_CMD_PROBE_CLIENT);
 
        if (IS_ERR(hdr)) {
@@ -6828,10 +6828,10 @@ static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
        if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
                return -EOPNOTSUPP;
 
-       if (rdev->ap_beacons_nlpid)
+       if (rdev->ap_beacons_nlportid)
                return -EBUSY;
 
-       rdev->ap_beacons_nlpid = info->snd_pid;
+       rdev->ap_beacons_nlportid = info->snd_portid;
 
        return 0;
 }
@@ -7628,12 +7628,12 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
 static int nl80211_send_scan_msg(struct sk_buff *msg,
                                 struct cfg80211_registered_device *rdev,
                                 struct wireless_dev *wdev,
-                                u32 pid, u32 seq, int flags,
+                                u32 portid, u32 seq, int flags,
                                 u32 cmd)
 {
        void *hdr;
 
-       hdr = nl80211hdr_put(msg, pid, seq, flags, cmd);
+       hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
        if (!hdr)
                return -1;
 
@@ -7657,11 +7657,11 @@ static int
 nl80211_send_sched_scan_msg(struct sk_buff *msg,
                            struct cfg80211_registered_device *rdev,
                            struct net_device *netdev,
-                           u32 pid, u32 seq, int flags, u32 cmd)
+                           u32 portid, u32 seq, int flags, u32 cmd)
 {
        void *hdr;
 
-       hdr = nl80211hdr_put(msg, pid, seq, flags, cmd);
+       hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
        if (!hdr)
                return -1;
 
@@ -8370,9 +8370,9 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
        struct sk_buff *msg;
        void *hdr;
        int err;
-       u32 nlpid = ACCESS_ONCE(wdev->ap_unexpected_nlpid);
+       u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid);
 
-       if (!nlpid)
+       if (!nlportid)
                return false;
 
        msg = nlmsg_new(100, gfp);
@@ -8396,7 +8396,7 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
                return true;
        }
 
-       genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
+       genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
        return true;
 
  nla_put_failure:
@@ -8420,7 +8420,7 @@ bool nl80211_unexpected_4addr_frame(struct net_device *dev,
 }
 
 int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
-                     struct wireless_dev *wdev, u32 nlpid,
+                     struct wireless_dev *wdev, u32 nlportid,
                      int freq, int sig_dbm,
                      const u8 *buf, size_t len, gfp_t gfp)
 {
@@ -8449,7 +8449,7 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
 
        genlmsg_end(msg, hdr);
 
-       return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
+       return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
 
  nla_put_failure:
        genlmsg_cancel(msg, hdr);
@@ -8804,9 +8804,9 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
        struct sk_buff *msg;
        void *hdr;
-       u32 nlpid = ACCESS_ONCE(rdev->ap_beacons_nlpid);
+       u32 nlportid = ACCESS_ONCE(rdev->ap_beacons_nlportid);
 
-       if (!nlpid)
+       if (!nlportid)
                return;
 
        msg = nlmsg_new(len + 100, gfp);
@@ -8829,7 +8829,7 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
 
        genlmsg_end(msg, hdr);
 
-       genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
+       genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
        return;
 
  nla_put_failure:
@@ -8853,9 +8853,9 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
 
        list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
                list_for_each_entry_rcu(wdev, &rdev->wdev_list, list)
-                       cfg80211_mlme_unregister_socket(wdev, notify->pid);
-               if (rdev->ap_beacons_nlpid == notify->pid)
-                       rdev->ap_beacons_nlpid = 0;
+                       cfg80211_mlme_unregister_socket(wdev, notify->portid);
+               if (rdev->ap_beacons_nlportid == notify->portid)
+                       rdev->ap_beacons_nlportid = 0;
        }
 
        rcu_read_unlock();
index 7856c33898fa7f791445067180a9c32a56befe89..30edad44e7fc15bb4db910688f60be5b8343425c 100644 (file)
@@ -166,7 +166,7 @@ static DEFINE_SPINLOCK(xfrm_state_gc_lock);
 int __xfrm_state_delete(struct xfrm_state *x);
 
 int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
-void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
+void km_state_expired(struct xfrm_state *x, int hard, u32 portid);
 
 static struct xfrm_state_afinfo *xfrm_state_lock_afinfo(unsigned int family)
 {
@@ -1674,13 +1674,13 @@ void km_state_notify(struct xfrm_state *x, const struct km_event *c)
 EXPORT_SYMBOL(km_policy_notify);
 EXPORT_SYMBOL(km_state_notify);
 
-void km_state_expired(struct xfrm_state *x, int hard, u32 pid)
+void km_state_expired(struct xfrm_state *x, int hard, u32 portid)
 {
        struct net *net = xs_net(x);
        struct km_event c;
 
        c.data.hard = hard;
-       c.pid = pid;
+       c.portid = portid;
        c.event = XFRM_MSG_EXPIRE;
        km_state_notify(x, &c);
 
@@ -1726,13 +1726,13 @@ int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport)
 }
 EXPORT_SYMBOL(km_new_mapping);
 
-void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid)
+void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid)
 {
        struct net *net = xp_net(pol);
        struct km_event c;
 
        c.data.hard = hard;
-       c.pid = pid;
+       c.portid = portid;
        c.event = XFRM_MSG_POLEXPIRE;
        km_policy_notify(pol, dir, &c);
 
index ab58034c42d60483d68df00567d0498d923972f0..5d6eb4b3c089f406ebf4397e034e26152bcb40dc 100644 (file)
@@ -603,7 +603,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
        }
 
        c.seq = nlh->nlmsg_seq;
-       c.pid = nlh->nlmsg_pid;
+       c.portid = nlh->nlmsg_pid;
        c.event = nlh->nlmsg_type;
 
        km_state_notify(x, &c);
@@ -676,7 +676,7 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
                goto out;
 
        c.seq = nlh->nlmsg_seq;
-       c.pid = nlh->nlmsg_pid;
+       c.portid = nlh->nlmsg_pid;
        c.event = nlh->nlmsg_type;
        km_state_notify(x, &c);
 
@@ -826,7 +826,7 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
        struct nlmsghdr *nlh;
        int err;
 
-       nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq,
+       nlh = nlmsg_put(skb, NETLINK_CB(in_skb).portid, sp->nlmsg_seq,
                        XFRM_MSG_NEWSA, sizeof(*p), sp->nlmsg_flags);
        if (nlh == NULL)
                return -EMSGSIZE;
@@ -904,7 +904,7 @@ static inline size_t xfrm_spdinfo_msgsize(void)
 }
 
 static int build_spdinfo(struct sk_buff *skb, struct net *net,
-                        u32 pid, u32 seq, u32 flags)
+                        u32 portid, u32 seq, u32 flags)
 {
        struct xfrmk_spdinfo si;
        struct xfrmu_spdinfo spc;
@@ -913,7 +913,7 @@ static int build_spdinfo(struct sk_buff *skb, struct net *net,
        int err;
        u32 *f;
 
-       nlh = nlmsg_put(skb, pid, seq, XFRM_MSG_NEWSPDINFO, sizeof(u32), 0);
+       nlh = nlmsg_put(skb, portid, seq, XFRM_MSG_NEWSPDINFO, sizeof(u32), 0);
        if (nlh == NULL) /* shouldn't really happen ... */
                return -EMSGSIZE;
 
@@ -946,17 +946,17 @@ static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
        struct net *net = sock_net(skb->sk);
        struct sk_buff *r_skb;
        u32 *flags = nlmsg_data(nlh);
-       u32 spid = NETLINK_CB(skb).pid;
+       u32 sportid = NETLINK_CB(skb).portid;
        u32 seq = nlh->nlmsg_seq;
 
        r_skb = nlmsg_new(xfrm_spdinfo_msgsize(), GFP_ATOMIC);
        if (r_skb == NULL)
                return -ENOMEM;
 
-       if (build_spdinfo(r_skb, net, spid, seq, *flags) < 0)
+       if (build_spdinfo(r_skb, net, sportid, seq, *flags) < 0)
                BUG();
 
-       return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid);
+       return nlmsg_unicast(net->xfrm.nlsk, r_skb, sportid);
 }
 
 static inline size_t xfrm_sadinfo_msgsize(void)
@@ -967,7 +967,7 @@ static inline size_t xfrm_sadinfo_msgsize(void)
 }
 
 static int build_sadinfo(struct sk_buff *skb, struct net *net,
-                        u32 pid, u32 seq, u32 flags)
+                        u32 portid, u32 seq, u32 flags)
 {
        struct xfrmk_sadinfo si;
        struct xfrmu_sadhinfo sh;
@@ -975,7 +975,7 @@ static int build_sadinfo(struct sk_buff *skb, struct net *net,
        int err;
        u32 *f;
 
-       nlh = nlmsg_put(skb, pid, seq, XFRM_MSG_NEWSADINFO, sizeof(u32), 0);
+       nlh = nlmsg_put(skb, portid, seq, XFRM_MSG_NEWSADINFO, sizeof(u32), 0);
        if (nlh == NULL) /* shouldn't really happen ... */
                return -EMSGSIZE;
 
@@ -1003,17 +1003,17 @@ static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
        struct net *net = sock_net(skb->sk);
        struct sk_buff *r_skb;
        u32 *flags = nlmsg_data(nlh);
-       u32 spid = NETLINK_CB(skb).pid;
+       u32 sportid = NETLINK_CB(skb).portid;
        u32 seq = nlh->nlmsg_seq;
 
        r_skb = nlmsg_new(xfrm_sadinfo_msgsize(), GFP_ATOMIC);
        if (r_skb == NULL)
                return -ENOMEM;
 
-       if (build_sadinfo(r_skb, net, spid, seq, *flags) < 0)
+       if (build_sadinfo(r_skb, net, sportid, seq, *flags) < 0)
                BUG();
 
-       return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid);
+       return nlmsg_unicast(net->xfrm.nlsk, r_skb, sportid);
 }
 
 static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -1033,7 +1033,7 @@ static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
        if (IS_ERR(resp_skb)) {
                err = PTR_ERR(resp_skb);
        } else {
-               err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).pid);
+               err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).portid);
        }
        xfrm_state_put(x);
 out_noput:
@@ -1114,7 +1114,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
                goto out;
        }
 
-       err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).pid);
+       err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).portid);
 
 out:
        xfrm_state_put(x);
@@ -1401,7 +1401,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 
        c.event = nlh->nlmsg_type;
        c.seq = nlh->nlmsg_seq;
-       c.pid = nlh->nlmsg_pid;
+       c.portid = nlh->nlmsg_pid;
        km_policy_notify(xp, p->dir, &c);
 
        xfrm_pol_put(xp);
@@ -1486,7 +1486,7 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr
        struct nlmsghdr *nlh;
        int err;
 
-       nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq,
+       nlh = nlmsg_put(skb, NETLINK_CB(in_skb).portid, sp->nlmsg_seq,
                        XFRM_MSG_NEWPOLICY, sizeof(*p), sp->nlmsg_flags);
        if (nlh == NULL)
                return -EMSGSIZE;
@@ -1621,7 +1621,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
                        err = PTR_ERR(resp_skb);
                } else {
                        err = nlmsg_unicast(net->xfrm.nlsk, resp_skb,
-                                           NETLINK_CB(skb).pid);
+                                           NETLINK_CB(skb).portid);
                }
        } else {
                uid_t loginuid = audit_get_loginuid(current);
@@ -1638,7 +1638,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
                c.data.byid = p->index;
                c.event = nlh->nlmsg_type;
                c.seq = nlh->nlmsg_seq;
-               c.pid = nlh->nlmsg_pid;
+               c.portid = nlh->nlmsg_pid;
                km_policy_notify(xp, p->dir, &c);
        }
 
@@ -1668,7 +1668,7 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
        c.data.proto = p->proto;
        c.event = nlh->nlmsg_type;
        c.seq = nlh->nlmsg_seq;
-       c.pid = nlh->nlmsg_pid;
+       c.portid = nlh->nlmsg_pid;
        c.net = net;
        km_state_notify(NULL, &c);
 
@@ -1695,7 +1695,7 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct
        struct nlmsghdr *nlh;
        int err;
 
-       nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0);
+       nlh = nlmsg_put(skb, c->portid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -1777,11 +1777,11 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
        spin_lock_bh(&x->lock);
        c.data.aevent = p->flags;
        c.seq = nlh->nlmsg_seq;
-       c.pid = nlh->nlmsg_pid;
+       c.portid = nlh->nlmsg_pid;
 
        if (build_aevent(r_skb, x, &c) < 0)
                BUG();
-       err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).pid);
+       err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).portid);
        spin_unlock_bh(&x->lock);
        xfrm_state_put(x);
        return err;
@@ -1827,7 +1827,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
 
        c.event = nlh->nlmsg_type;
        c.seq = nlh->nlmsg_seq;
-       c.pid = nlh->nlmsg_pid;
+       c.portid = nlh->nlmsg_pid;
        c.data.aevent = XFRM_AE_CU;
        km_state_notify(x, &c);
        err = 0;
@@ -1862,7 +1862,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
        c.data.type = type;
        c.event = nlh->nlmsg_type;
        c.seq = nlh->nlmsg_seq;
-       c.pid = nlh->nlmsg_pid;
+       c.portid = nlh->nlmsg_pid;
        c.net = net;
        km_policy_notify(NULL, 0, &c);
        return 0;
@@ -1930,7 +1930,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
                // reset the timers here?
                WARN(1, "Dont know what to do with soft policy expire\n");
        }
-       km_policy_expired(xp, p->dir, up->hard, current->pid);
+       km_policy_expired(xp, p->dir, up->hard, nlh->nlmsg_pid);
 
 out:
        xfrm_pol_put(xp);
@@ -1958,7 +1958,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
        err = -EINVAL;
        if (x->km.state != XFRM_STATE_VALID)
                goto out;
-       km_state_expired(x, ue->hard, current->pid);
+       km_state_expired(x, ue->hard, nlh->nlmsg_pid);
 
        if (ue->hard) {
                uid_t loginuid = audit_get_loginuid(current);
@@ -2370,7 +2370,7 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, const struct
        struct nlmsghdr *nlh;
        int err;
 
-       nlh = nlmsg_put(skb, c->pid, 0, XFRM_MSG_EXPIRE, sizeof(*ue), 0);
+       nlh = nlmsg_put(skb, c->portid, 0, XFRM_MSG_EXPIRE, sizeof(*ue), 0);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -2429,7 +2429,7 @@ static int xfrm_notify_sa_flush(const struct km_event *c)
        if (skb == NULL)
                return -ENOMEM;
 
-       nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_FLUSHSA, sizeof(*p), 0);
+       nlh = nlmsg_put(skb, c->portid, c->seq, XFRM_MSG_FLUSHSA, sizeof(*p), 0);
        if (nlh == NULL) {
                kfree_skb(skb);
                return -EMSGSIZE;
@@ -2497,7 +2497,7 @@ static int xfrm_notify_sa(struct xfrm_state *x, const struct km_event *c)
        if (skb == NULL)
                return -ENOMEM;
 
-       nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0);
+       nlh = nlmsg_put(skb, c->portid, c->seq, c->event, headlen, 0);
        err = -EMSGSIZE;
        if (nlh == NULL)
                goto out_free_skb;
@@ -2696,7 +2696,7 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,
        struct nlmsghdr *nlh;
        int err;
 
-       nlh = nlmsg_put(skb, c->pid, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe), 0);
+       nlh = nlmsg_put(skb, c->portid, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe), 0);
        if (nlh == NULL)
                return -EMSGSIZE;
 
@@ -2756,7 +2756,7 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, const struct km_e
        if (skb == NULL)
                return -ENOMEM;
 
-       nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0);
+       nlh = nlmsg_put(skb, c->portid, c->seq, c->event, headlen, 0);
        err = -EMSGSIZE;
        if (nlh == NULL)
                goto out_free_skb;
@@ -2810,7 +2810,7 @@ static int xfrm_notify_policy_flush(const struct km_event *c)
        if (skb == NULL)
                return -ENOMEM;
 
-       nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0, 0);
+       nlh = nlmsg_put(skb, c->portid, c->seq, XFRM_MSG_FLUSHPOLICY, 0, 0);
        err = -EMSGSIZE;
        if (nlh == NULL)
                goto out_free_skb;
@@ -2963,7 +2963,7 @@ static int __net_init xfrm_user_net_init(struct net *net)
                .input  = xfrm_netlink_rcv,
        };
 
-       nlsk = netlink_kernel_create(net, NETLINK_XFRM, THIS_MODULE, &cfg);
+       nlsk = netlink_kernel_create(net, NETLINK_XFRM, &cfg);
        if (nlsk == NULL)
                return -ENOMEM;
        net->xfrm.nlsk_stash = nlsk; /* Don't set to NULL */
index 8a77725423e0848e671a1f5bdb021fa414de6059..14d810ead42078482807666a41902e4cb24161c0 100644 (file)
@@ -113,13 +113,12 @@ static int __init selnl_init(void)
 {
        struct netlink_kernel_cfg cfg = {
                .groups = SELNLGRP_MAX,
+               .flags  = NL_CFG_F_NONROOT_RECV,
        };
 
-       selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX,
-                                     THIS_MODULE, &cfg);
+       selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX, &cfg);
        if (selnl == NULL)
                panic("SELinux:  Cannot create netlink socket.");
-       netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV);
        return 0;
 }