Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
[powerpc.git] / net / sctp / ipv6.c
index e6bb087..0b9c49b 100644 (file)
@@ -53,7 +53,6 @@
 #include <linux/socket.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
-#include <linux/sched.h>
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/netdevice.h>
 
 #include <asm/uaccess.h>
 
+/* Event handler for inet6 address addition/deletion events.  */
+static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
+                               void *ptr)
+{
+       struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
+       struct sctp_sockaddr_entry *addr;
+       struct list_head *pos, *temp;
+
+       switch (ev) {
+       case NETDEV_UP:
+               addr = kmalloc(sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC);
+               if (addr) {
+                       addr->a.v6.sin6_family = AF_INET6;
+                       addr->a.v6.sin6_port = 0;
+                       memcpy(&addr->a.v6.sin6_addr, &ifa->addr,
+                                sizeof(struct in6_addr));
+                       addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex;
+                       list_add_tail(&addr->list, &sctp_local_addr_list);
+               }
+               break;
+       case NETDEV_DOWN:
+               list_for_each_safe(pos, temp, &sctp_local_addr_list) {
+                       addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+                       if (ipv6_addr_equal(&addr->a.v6.sin6_addr, &ifa->addr)) {
+                               list_del(pos);
+                               kfree(addr);
+                               break;
+                       }
+               }
+
+               break;
+       }
+
+       return NOTIFY_DONE;
+}
+
 static struct notifier_block sctp_inet6addr_notifier = {
-       .notifier_call = sctp_inetaddr_event,
+       .notifier_call = sctp_inet6addr_event,
 };
 
 /* ICMP error handler. */
@@ -200,7 +235,7 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
        ipv6_addr_copy(&fl.fl6_dst, &daddr->v6.sin6_addr);
        if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
                fl.oif = daddr->v6.sin6_scope_id;
-       
+
 
        SCTP_DEBUG_PRINTK("%s: DST=" NIP6_FMT " ",
                          __FUNCTION__, NIP6(fl.fl6_dst));
@@ -325,7 +360,7 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist,
                return;
        }
 
-       read_lock(&in6_dev->lock);
+       read_lock_bh(&in6_dev->lock);
        for (ifp = in6_dev->addr_list; ifp; ifp = ifp->if_next) {
                /* Add the address to the local list.  */
                addr = t_new(struct sctp_sockaddr_entry, GFP_ATOMIC);
@@ -339,7 +374,7 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist,
                }
        }
 
-       read_unlock(&in6_dev->lock);
+       read_unlock_bh(&in6_dev->lock);
        rcu_read_unlock();
 }
 
@@ -371,7 +406,7 @@ static void sctp_v6_from_skb(union sctp_addr *addr,struct sk_buff *skb,
 static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
 {
        addr->v6.sin6_family = AF_INET6;
-       addr->v6.sin6_port = inet_sk(sk)->num;
+       addr->v6.sin6_port = 0;
        addr->v6.sin6_addr = inet6_sk(sk)->rcv_saddr;
 }
 
@@ -478,7 +513,7 @@ static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
 }
 
 /* Initialize addr struct to INADDR_ANY. */
-static void sctp_v6_inaddr_any(union sctp_addr *addr, unsigned short port)
+static void sctp_v6_inaddr_any(union sctp_addr *addr, __be16 port)
 {
        memset(addr, 0x00, sizeof(union sctp_addr));
        addr->v6.sin6_family = AF_INET6;
@@ -853,7 +888,7 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
  * Returns number of addresses supported.
  */
 static int sctp_inet6_supported_addrs(const struct sctp_sock *opt,
-                                     __u16 *types)
+                                     __be16 *types)
 {
        types[0] = SCTP_PARAM_IPV4_ADDRESS;
        types[1] = SCTP_PARAM_IPV6_ADDRESS;