]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
support ipv4 broadcast specification
authorDaniel Lezcano <daniel.lezcano@free.fr>
Tue, 18 May 2010 15:40:04 +0000 (17:40 +0200)
committerDaniel Lezcano <dlezcano@fr.ibm.com>
Tue, 18 May 2010 15:40:04 +0000 (17:40 +0200)
Add the broadcast specification, if none is specified, it is automatically
computed from the addr & mask.

syntax:
lxc.network.ipv4 = 172.20.0.2/24 172.20.255.255

Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
src/lxc/network.c
src/lxc/network.h

index f1f0beb11126bb601ceaa46a22925f35b7183b72..82b7f536ab72e5f12aa69292fe2b1d6625015184 100644 (file)
@@ -654,52 +654,53 @@ int lxc_neigh_proxy_off(const char *name, int family)
 
 int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
 {
-    unsigned char *data;
-    char c;
-    int i = 0;
-    unsigned val;
-
-    sockaddr->sa_family = ARPHRD_ETHER;
-    data = (unsigned char *)sockaddr->sa_data;
-
-    while ((*macaddr != '\0') && (i < ETH_ALEN)) {
-       val = 0;
-       c = *macaddr++;
-       if (isdigit(c))
-           val = c - '0';
-       else if (c >= 'a' && c <= 'f')
-           val = c - 'a' + 10;
-       else if (c >= 'A' && c <= 'F')
-           val = c - 'A' + 10;
-       else {
-           return -EINVAL;
+       unsigned char *data;
+       char c;
+       int i = 0;
+       unsigned val;
+
+       sockaddr->sa_family = ARPHRD_ETHER;
+       data = (unsigned char *)sockaddr->sa_data;
+
+       while ((*macaddr != '\0') && (i < ETH_ALEN)) {
+           val = 0;
+           c = *macaddr++;
+           if (isdigit(c))
+                   val = c - '0';
+           else if (c >= 'a' && c <= 'f')
+                   val = c - 'a' + 10;
+           else if (c >= 'A' && c <= 'F')
+                   val = c - 'A' + 10;
+           else {
+                   return -EINVAL;
+           }
+           val <<= 4;
+           c = *macaddr;
+           if (isdigit(c))
+                   val |= c - '0';
+           else if (c >= 'a' && c <= 'f')
+                   val |= c - 'a' + 10;
+           else if (c >= 'A' && c <= 'F')
+                   val |= c - 'A' + 10;
+           else if (c == ':' || c == 0)
+                   val >>= 4;
+           else {
+                   return -EINVAL;
+           }
+           if (c != 0)
+                   macaddr++;
+           *data++ = (unsigned char) (val & 0377);
+           i++;
+
+           if (*macaddr == ':')
+                   macaddr++;
        }
-       val <<= 4;
-       c = *macaddr;
-       if (isdigit(c))
-           val |= c - '0';
-       else if (c >= 'a' && c <= 'f')
-           val |= c - 'a' + 10;
-       else if (c >= 'A' && c <= 'F')
-           val |= c - 'A' + 10;
-       else if (c == ':' || c == 0)
-           val >>= 4;
-       else {
-           return -EINVAL;
-       }
-       if (c != 0)
-           macaddr++;
-       *data++ = (unsigned char) (val & 0377);
-       i++;
-
-       if (*macaddr == ':')
-           macaddr++;
-    }
 
-    return 0;
+       return 0;
 }
 
-int lxc_ip_addr_add(int family, int ifindex, void *addr, int prefix)
+static int ip_addr_add(int family, int ifindex,
+                      void *addr, void *bcast, void *acast, int prefix)
 {
        struct nl_handler nlh;
        struct nlmsg *nlmsg = NULL, *answer = NULL;
@@ -724,7 +725,8 @@ int lxc_ip_addr_add(int family, int ifindex, void *addr, int prefix)
                goto out;
 
        ip_req = (struct ip_req *)nlmsg;
-        ip_req->nlmsg.nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+        ip_req->nlmsg.nlmsghdr.nlmsg_len =
+               NLMSG_LENGTH(sizeof(struct ifaddrmsg));
         ip_req->nlmsg.nlmsghdr.nlmsg_flags =
                NLM_F_ACK|NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL;
         ip_req->nlmsg.nlmsghdr.nlmsg_type = RTM_NEWADDR;
@@ -740,10 +742,13 @@ int lxc_ip_addr_add(int family, int ifindex, void *addr, int prefix)
        if (nla_put_buffer(nlmsg, IFA_ADDRESS, addr, addrlen))
                goto out;
 
-/*     if (in_bcast.s_addr != INADDR_ANY) */
-/*             if (nla_put_buffer(nlmsg, IFA_BROADCAST, &in_bcast, */
-/*                                sizeof(in_bcast))) */
-/*                     goto out; */
+       if (bcast && nla_put_buffer(nlmsg, IFA_BROADCAST, bcast, addrlen))
+               goto out;
+
+       /* TODO : multicast, anycast with ipv6 */
+       err = EPROTONOSUPPORT;
+       if ((bcast || acast) && family == AF_INET6)
+               goto out;
 
        err = netlink_transaction(&nlh, nlmsg, answer);
 out:
@@ -753,6 +758,19 @@ out:
        return err;
 }
 
+int lxc_ipv6_addr_add(int ifindex, struct in6_addr *addr,
+                     struct in6_addr *mcast,
+                     struct in6_addr *acast, int prefix)
+{
+       return ip_addr_add(AF_INET6, ifindex, addr, mcast, acast, prefix);
+}
+
+int lxc_ipv4_addr_add(int ifindex, struct in_addr *addr,
+                     struct in_addr *bcast, int prefix)
+{
+       return ip_addr_add(AF_INET, ifindex, addr, bcast, NULL, prefix);
+}
+
 /*
  * There is a lxc_bridge_attach, but no need of a bridge detach
  * as automatically done by kernel when device deleted.
index 0d743433e1871e38792edcc01499d4006a190915..fa7c6ff4ec870f04ca4fc9c0ba9a3582a797087d 100644 (file)
@@ -91,7 +91,12 @@ extern int lxc_ip_forward_off(const char *name, int family);
 /*
  * Set ip address
  */
-extern int lxc_ip_addr_add(int family, int ifindex, void *addr, int prefix);
+extern int lxc_ipv6_addr_add(int ifindex, struct in6_addr *addr,
+                            struct in6_addr *mcast,
+                            struct in6_addr *acast, int prefix);
+
+extern int lxc_ipv4_addr_add(int ifindex, struct in_addr *addr,
+                            struct in_addr *bcast, int prefix);
 
 /*
  * Attach an interface to the bridge