Make sock_sendpage() use kernel_sendpage()
[safe/jmp/linux-2.6] / net / atm / mpc.c
index 7c85aa5..e5bf114 100644 (file)
@@ -62,11 +62,13 @@ static void MPOA_cache_impos_rcvd(struct k_message *msg, struct mpoa_client *mpc
 static void set_mpc_ctrl_addr_rcvd(struct k_message *mesg, struct mpoa_client *mpc);
 static void set_mps_mac_addr_rcvd(struct k_message *mesg, struct mpoa_client *mpc);
 
-static uint8_t *copy_macs(struct mpoa_client *mpc, uint8_t *router_mac,
-                         uint8_t *tlvs, uint8_t mps_macs, uint8_t device_type);
+static const uint8_t *copy_macs(struct mpoa_client *mpc,
+                               const uint8_t *router_mac,
+                               const uint8_t *tlvs, uint8_t mps_macs,
+                               uint8_t device_type);
 static void purge_egress_shortcut(struct atm_vcc *vcc, eg_cache_entry *entry);
 
-static void send_set_mps_ctrl_addr(char *addr, struct mpoa_client *mpc);
+static void send_set_mps_ctrl_addr(const char *addr, struct mpoa_client *mpc);
 static void mpoad_close(struct atm_vcc *vcc);
 static int msg_from_mpoad(struct atm_vcc *vcc, struct sk_buff *skb);
 
@@ -230,8 +232,8 @@ void atm_mpoa_disp_qos(struct seq_file *m)
        seq_printf(m, "IP address\n  TX:max_pcr pcr     min_pcr max_cdv max_sdu\n  RX:max_pcr pcr     min_pcr max_cdv max_sdu\n");
 
        while (qos != NULL) {
-               seq_printf(m, "%u.%u.%u.%u\n     %-7d %-7d %-7d %-7d %-7d\n     %-7d %-7d %-7d %-7d %-7d\n",
-                               NIPQUAD(qos->ipaddr),
+               seq_printf(m, "%pI4\n     %-7d %-7d %-7d %-7d %-7d\n     %-7d %-7d %-7d %-7d %-7d\n",
+                               &qos->ipaddr,
                                qos->qos.txtp.max_pcr, qos->qos.txtp.pcr, qos->qos.txtp.min_pcr, qos->qos.txtp.max_cdv, qos->qos.txtp.max_sdu,
                                qos->qos.rxtp.max_pcr, qos->qos.rxtp.pcr, qos->qos.rxtp.min_pcr, qos->qos.rxtp.max_cdv, qos->qos.rxtp.max_sdu);
                qos = qos->next;
@@ -244,7 +246,7 @@ static struct net_device *find_lec_by_itfnum(int itf)
        char name[IFNAMSIZ];
 
        sprintf(name, "lec%d", itf);
-       dev = dev_get_by_name(name);
+       dev = dev_get_by_name(&init_net, name);
 
        return dev;
 }
@@ -284,33 +286,32 @@ static void start_mpc(struct mpoa_client *mpc, struct net_device *dev)
 {
 
        dprintk("mpoa: (%s) start_mpc:\n", mpc->dev->name);
-       if (dev->hard_start_xmit == NULL) {
-               printk("mpoa: (%s) start_mpc: dev->hard_start_xmit == NULL, not starting\n",
-                      dev->name);
-               return;
+       if (!dev->netdev_ops)
+               printk("mpoa: (%s) start_mpc  not starting\n", dev->name);
+       else {
+               mpc->old_ops = dev->netdev_ops;
+               mpc->new_ops = *mpc->old_ops;
+               mpc->new_ops.ndo_start_xmit = mpc_send_packet;
+               dev->netdev_ops = &mpc->new_ops;
        }
-       mpc->old_hard_start_xmit = dev->hard_start_xmit;
-       dev->hard_start_xmit = mpc_send_packet;
-
-       return;
 }
 
 static void stop_mpc(struct mpoa_client *mpc)
 {
-
+       struct net_device *dev = mpc->dev;
        dprintk("mpoa: (%s) stop_mpc:", mpc->dev->name);
 
        /* Lets not nullify lec device's dev->hard_start_xmit */
-       if (mpc->dev->hard_start_xmit != mpc_send_packet) {
+       if (dev->netdev_ops != &mpc->new_ops) {
                dprintk(" mpc already stopped, not fatal\n");
                return;
        }
        dprintk("\n");
-       mpc->dev->hard_start_xmit = mpc->old_hard_start_xmit;
-       mpc->old_hard_start_xmit = NULL;
-       /* close_shortcuts(mpc);    ??? FIXME */
 
-       return;
+       dev->netdev_ops = mpc->old_ops;
+       mpc->old_ops = NULL;
+
+       /* close_shortcuts(mpc);    ??? FIXME */
 }
 
 static const char *mpoa_device_type_string(char type) __attribute__ ((unused));
@@ -339,8 +340,8 @@ static const char *mpoa_device_type_string(char type)
 }
 
 /*
- * lec device calls this via its dev->priv->lane2_ops->associate_indicator()
- * when it sees a TLV in LE_ARP packet.
+ * lec device calls this via its netdev_priv(dev)->lane2_ops
+ * ->associate_indicator() when it sees a TLV in LE_ARP packet.
  * We fill in the pointer above when we see a LANE2 lec initializing
  * See LANE2 spec 3.1.5
  *
@@ -351,12 +352,12 @@ static const char *mpoa_device_type_string(char type)
  * lec sees a TLV it uses the pointer to call this function.
  *
  */
-static void lane2_assoc_ind(struct net_device *dev, uint8_t *mac_addr,
-                           uint8_t *tlvs, uint32_t sizeoftlvs)
+static void lane2_assoc_ind(struct net_device *dev, const u8 *mac_addr,
+                           const u8 *tlvs, u32 sizeoftlvs)
 {
        uint32_t type;
        uint8_t length, mpoa_device_type, number_of_mps_macs;
-       uint8_t *end_of_tlvs;
+       const uint8_t *end_of_tlvs;
        struct mpoa_client *mpc;
 
        mpoa_device_type = number_of_mps_macs = 0; /* silence gcc */
@@ -430,8 +431,10 @@ static void lane2_assoc_ind(struct net_device *dev, uint8_t *mac_addr,
  * plus the possible MAC address(es) to mpc->mps_macs.
  * For a freshly allocated MPOA client mpc->mps_macs == 0.
  */
-static uint8_t *copy_macs(struct mpoa_client *mpc, uint8_t *router_mac,
-                         uint8_t *tlvs, uint8_t mps_macs, uint8_t device_type)
+static const uint8_t *copy_macs(struct mpoa_client *mpc,
+                               const uint8_t *router_mac,
+                               const uint8_t *tlvs, uint8_t mps_macs,
+                               uint8_t device_type)
 {
        int num_macs;
        num_macs = (mps_macs > 1) ? mps_macs : 1;
@@ -527,7 +530,6 @@ static int send_via_shortcut(struct sk_buff *skb, struct mpoa_client *mpc)
  */
 static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
-       int retval;
        struct mpoa_client *mpc;
        struct ethhdr *eth;
        int i = 0;
@@ -542,6 +544,13 @@ static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev)
        if (eth->h_proto != htons(ETH_P_IP))
                goto non_ip; /* Multi-Protocol Over ATM :-) */
 
+       /* Weed out funny packets (e.g., AF_PACKET or raw). */
+       if (skb->len < ETH_HLEN + sizeof(struct iphdr))
+               goto non_ip;
+       skb_set_network_header(skb, ETH_HLEN);
+       if (skb->len < ETH_HLEN + ip_hdr(skb)->ihl * 4 || ip_hdr(skb)->ihl < 5)
+               goto non_ip;
+
        while (i < mpc->number_of_mps_macs) {
                if (!compare_ether_addr(eth->h_dest, (mpc->mps_macs + i*ETH_ALEN)))
                        if ( send_via_shortcut(skb, mpc) == 0 )           /* try shortcut */
@@ -550,9 +559,7 @@ static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev)
        }
 
  non_ip:
-       retval = mpc->old_hard_start_xmit(skb,dev);
-
-       return retval;
+       return mpc->old_ops->ndo_start_xmit(skb,dev);
 }
 
 static int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg)
@@ -584,8 +591,8 @@ static int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg)
                        if (in_entry != NULL) mpc->in_ops->put(in_entry);
                        return -EINVAL;
                }
-               printk("mpoa: (%s) mpc_vcc_attach: attaching ingress SVC, entry = %u.%u.%u.%u\n",
-                      mpc->dev->name, NIPQUAD(in_entry->ctrl_info.in_dst_ip));
+               printk("mpoa: (%s) mpc_vcc_attach: attaching ingress SVC, entry = %pI4\n",
+                      mpc->dev->name, &in_entry->ctrl_info.in_dst_ip);
                in_entry->shortcut = vcc;
                mpc->in_ops->put(in_entry);
        } else {
@@ -616,8 +623,8 @@ static void mpc_vcc_close(struct atm_vcc *vcc, struct net_device *dev)
        dprintk("mpoa: (%s) mpc_vcc_close:\n", dev->name);
        in_entry = mpc->in_ops->get_by_vcc(vcc, mpc);
        if (in_entry) {
-               dprintk("mpoa: (%s) mpc_vcc_close: ingress SVC closed ip = %u.%u.%u.%u\n",
-                      mpc->dev->name, NIPQUAD(in_entry->ctrl_info.in_dst_ip));
+               dprintk("mpoa: (%s) mpc_vcc_close: ingress SVC closed ip = %pI4\n",
+                      mpc->dev->name, &in_entry->ctrl_info.in_dst_ip);
                in_entry->shortcut = NULL;
                mpc->in_ops->put(in_entry);
        }
@@ -774,7 +781,7 @@ static int atm_mpoa_mpoad_attach (struct atm_vcc *vcc, int arg)
        }
 
        if (mpc->dev) { /* check if the lec is LANE2 capable */
-               priv = (struct lec_priv *)mpc->dev->priv;
+               priv = netdev_priv(mpc->dev);
                if (priv->lane_version < 2) {
                        dev_put(mpc->dev);
                        mpc->dev = NULL;
@@ -804,7 +811,7 @@ static int atm_mpoa_mpoad_attach (struct atm_vcc *vcc, int arg)
        return arg;
 }
 
-static void send_set_mps_ctrl_addr(char *addr, struct mpoa_client *mpc)
+static void send_set_mps_ctrl_addr(const char *addr, struct mpoa_client *mpc)
 {
        struct k_message mesg;
 
@@ -834,7 +841,7 @@ static void mpoad_close(struct atm_vcc *vcc)
 
        mpc->mpoad_vcc = NULL;
        if (mpc->dev) {
-               struct lec_priv *priv = (struct lec_priv *)mpc->dev->priv;
+               struct lec_priv *priv = netdev_priv(mpc->dev);
                priv->lane2_ops->associate_indicator = NULL;
                stop_mpc(mpc);
                dev_put(mpc->dev);
@@ -956,12 +963,16 @@ static int mpoa_event_listener(struct notifier_block *mpoa_notifier, unsigned lo
        struct lec_priv *priv;
 
        dev = (struct net_device *)dev_ptr;
+
+       if (!net_eq(dev_net(dev), &init_net))
+               return NOTIFY_DONE;
+
        if (dev->name == NULL || strncmp(dev->name, "lec", 3))
                return NOTIFY_DONE; /* we are only interested in lec:s */
 
        switch (event) {
        case NETDEV_REGISTER:       /* a new lec device was allocated */
-               priv = (struct lec_priv *)dev->priv;
+               priv = netdev_priv(dev);
                if (priv->lane_version < 2)
                        break;
                priv->lane2_ops->associate_indicator = lane2_assoc_ind;
@@ -1083,7 +1094,8 @@ static void check_qos_and_open_shortcut(struct k_message *msg, struct mpoa_clien
                                    entry->shortcut = eg_entry->shortcut;
                }
                if(entry->shortcut){
-                       dprintk("mpoa: (%s) using egress SVC to reach %u.%u.%u.%u\n",client->dev->name, NIPQUAD(dst_ip));
+                       dprintk("mpoa: (%s) using egress SVC to reach %pI4\n",
+                               client->dev->name, &dst_ip);
                        client->eg_ops->put(eg_entry);
                        return;
                }
@@ -1108,7 +1120,8 @@ static void MPOA_res_reply_rcvd(struct k_message *msg, struct mpoa_client *mpc)
        __be32 dst_ip = msg->content.in_info.in_dst_ip;
        in_cache_entry *entry = mpc->in_ops->get(dst_ip, mpc);
 
-       dprintk("mpoa: (%s) MPOA_res_reply_rcvd: ip %u.%u.%u.%u\n", mpc->dev->name, NIPQUAD(dst_ip));
+       dprintk("mpoa: (%s) MPOA_res_reply_rcvd: ip %pI4\n",
+               mpc->dev->name, &dst_ip);
        ddprintk("mpoa: (%s) MPOA_res_reply_rcvd() entry = %p", mpc->dev->name, entry);
        if(entry == NULL){
                printk("\nmpoa: (%s) ARGH, received res. reply for an entry that doesn't exist.\n", mpc->dev->name);
@@ -1156,14 +1169,14 @@ static void ingress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc)
        in_cache_entry *entry = mpc->in_ops->get_with_mask(dst_ip, mpc, mask);
 
        if(entry == NULL){
-               printk("mpoa: (%s) ingress_purge_rcvd: purge for a non-existing entry, ", mpc->dev->name);
-               printk("ip = %u.%u.%u.%u\n", NIPQUAD(dst_ip));
+               printk("mpoa: (%s) ingress_purge_rcvd: purge for a non-existing entry, ip = %pI4\n",
+                      mpc->dev->name, &dst_ip);
                return;
        }
 
        do {
-               dprintk("mpoa: (%s) ingress_purge_rcvd: removing an ingress entry, ip = %u.%u.%u.%u\n" ,
-                       mpc->dev->name, NIPQUAD(dst_ip));
+               dprintk("mpoa: (%s) ingress_purge_rcvd: removing an ingress entry, ip = %pI4\n",
+                       mpc->dev->name, &dst_ip);
                write_lock_bh(&mpc->ingress_lock);
                mpc->in_ops->remove_entry(entry, mpc);
                write_unlock_bh(&mpc->ingress_lock);
@@ -1307,7 +1320,7 @@ static void set_mpc_ctrl_addr_rcvd(struct k_message *mesg, struct mpoa_client *m
        dprintk("\n");
 
        if (mpc->dev) {
-               priv = (struct lec_priv *)mpc->dev->priv;
+               priv = netdev_priv(mpc->dev);
                retval = priv->lane2_ops->associate_req(mpc->dev, mpc->dev->dev_addr, tlv, sizeof(tlv));
                if (retval == 0)
                        printk("mpoa: (%s) MPOA device type TLV association failed\n", mpc->dev->name);
@@ -1457,7 +1470,7 @@ static void __exit atm_mpoa_cleanup(void)
                tmp = mpc->next;
                if (mpc->dev != NULL) {
                        stop_mpc(mpc);
-                       priv = (struct lec_priv *)mpc->dev->priv;
+                       priv = netdev_priv(mpc->dev);
                        if (priv->lane2_ops != NULL)
                                priv->lane2_ops->associate_indicator = NULL;
                }