]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/caif/chnl_net.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / net / caif / chnl_net.c
index 84a422c989414d31c502de65d13b74d51c6a8f0c..6008d6dc18a02283fdff763ba2186190208a8003 100644 (file)
@@ -76,6 +76,8 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
        struct chnl_net *priv  = container_of(layr, struct chnl_net, chnl);
        int pktlen;
        int err = 0;
+       const u8 *ip_version;
+       u8 buf;
 
        priv = container_of(layr, struct chnl_net, chnl);
 
@@ -90,7 +92,21 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
         * send the packet to the net stack.
         */
        skb->dev = priv->netdev;
-       skb->protocol = htons(ETH_P_IP);
+
+       /* check the version of IP */
+       ip_version = skb_header_pointer(skb, 0, 1, &buf);
+       if (!ip_version)
+               return -EINVAL;
+       switch (*ip_version >> 4) {
+       case 4:
+               skb->protocol = htons(ETH_P_IP);
+               break;
+       case 6:
+               skb->protocol = htons(ETH_P_IPV6);
+               break;
+       default:
+               return -EINVAL;
+       }
 
        /* If we change the header in loop mode, the checksum is corrupted. */
        if (priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP)
@@ -378,9 +394,7 @@ static void ipcaif_net_setup(struct net_device *dev)
        priv->conn_req.sockaddr.u.dgm.connection_id = -1;
        priv->flowenabled = false;
 
-       ASSERT_RTNL();
        init_waitqueue_head(&priv->netmgmt_wq);
-       list_add(&priv->list_field, &chnl_net_list);
 }
 
 
@@ -437,6 +451,8 @@ static int ipcaif_newlink(struct net *src_net, struct net_device *dev,
        ret = register_netdevice(dev);
        if (ret)
                pr_warn("device rtml registration failed\n");
+       else
+               list_add(&caifdev->list_field, &chnl_net_list);
        return ret;
 }