9ns: change parsecmd()'s size arg's type to size_t
[akaros.git] / kern / src / net / iproute.c
index 27db012..a6f5005 100644 (file)
@@ -1,6 +1,31 @@
-// INFERNO
-#include <vfs.h>
-#include <kfs.h>
+/* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+ * Portions Copyright © 1997-1999 Vita Nuova Limited
+ * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
+ *                                (www.vitanuova.com)
+ * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+ *
+ * Modified for the Akaros operating system:
+ * Copyright (c) 2013-2014 The Regents of the University of California
+ * Copyright (c) 2013-2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
 #include <slab.h>
 #include <kmalloc.h>
 #include <kref.h>
@@ -11,7 +36,7 @@
 #include <cpio.h>
 #include <pmap.h>
 #include <smp.h>
-#include <ip.h>
+#include <net/ip.h>
 
 static void walkadd(struct Fs *, struct route **, struct route *);
 static void addnode(struct Fs *, struct route **, struct route *);
@@ -23,6 +48,19 @@ struct route *v6freelist;
 rwlock_t routelock;
 uint32_t v4routegeneration, v6routegeneration;
 
+/*
+ * TODO: Change this to a proper release.
+ * At the moment this is difficult to do since deleting
+ * a route involves manipulating more data structures than
+ * a kref/struct route.  E.g., unlinking from the route tree
+ * requires access to a parent pointer, which doesn't exist
+ * in the route structure itself.
+ */
+static void route_release(struct kref *kref)
+{
+       (void)kref;
+}
+
 static void freeroute(struct route *r)
 {
        struct route **l;
@@ -62,7 +100,7 @@ static struct route *allocroute(int type)
        memset(r, 0, n);
        r->rt.type = type;
        r->rt.ifc = NULL;
-       kref_init(&r->rt.kref, fake_release, 1);
+       kref_init(&r->rt.kref, route_release, 1);
 
        return r;
 }
@@ -244,40 +282,40 @@ static void addnode(struct Fs *f, struct route **cur, struct route *new)
        }
 
        switch (rangecompare(new, p)) {
-               case Rpreceeds:
-                       addnode(f, &p->rt.left, new);
-                       break;
-               case Rfollows:
-                       addnode(f, &p->rt.right, new);
-                       break;
-               case Rcontains:
-                       /*
-                        *  if new node is superset
-                        *  of tree node,
-                        *  replace tree node and
-                        *  queue tree node to be
-                        *  merged into root.
-                        */
-                       *cur = new;
-                       new->rt.depth = 1;
-                       addqueue(&f->queue, p);
-                       break;
-               case Requals:
-                       /*
-                        *  supercede the old entry if the old one isn't
-                        *  a local interface.
-                        */
-                       if ((p->rt.type & Rifc) == 0) {
-                               p->rt.type = new->rt.type;
-                               p->rt.ifcid = -1;
-                               copygate(p, new);
-                       } else if (new->rt.type & Rifc)
-                               kref_get(&p->rt.kref, 1);
-                       freeroute(new);
-                       break;
-               case Rcontained:
-                       addnode(f, &p->rt.mid, new);
-                       break;
+       case Rpreceeds:
+               addnode(f, &p->rt.left, new);
+               break;
+       case Rfollows:
+               addnode(f, &p->rt.right, new);
+               break;
+       case Rcontains:
+               /*
+                *  if new node is superset
+                *  of tree node,
+                *  replace tree node and
+                *  queue tree node to be
+                *  merged into root.
+                */
+               *cur = new;
+               new->rt.depth = 1;
+               addqueue(&f->queue, p);
+               break;
+       case Requals:
+               /*
+                *  supercede the old entry if the old one isn't
+                *  a local interface.
+                */
+               if ((p->rt.type & Rifc) == 0) {
+                       p->rt.type = new->rt.type;
+                       p->rt.ifcid = -1;
+                       copygate(p, new);
+               } else if (new->rt.type & Rifc)
+                       kref_get(&p->rt.kref, 1);
+               freeroute(new);
+               break;
+       case Rcontained:
+               addnode(f, &p->rt.mid, new);
+               break;
        }
 
        balancetree(cur);
@@ -285,9 +323,8 @@ static void addnode(struct Fs *f, struct route **cur, struct route *new)
 
 #define        V4H(a)  ((a&0x07ffffff)>>(32-Lroot-5))
 
-void
-v4addroute(struct Fs *f, char *tag, uint8_t * a, uint8_t * mask,
-                  uint8_t * gate, int type)
+void v4addroute(struct Fs *f, char *tag, uint8_t *a, uint8_t *mask,
+               uint8_t *gate, int type)
 {
        struct route *p;
        uint32_t sa;
@@ -324,9 +361,8 @@ v4addroute(struct Fs *f, char *tag, uint8_t * a, uint8_t * mask,
 #define        V6H(a)  (((a)[IPllen-1] & 0x07ffffff)>>(32-Lroot-5))
 #define ISDFLT(a, mask, tag) ((ipcmp((a),v6Unspecified)==0) && (ipcmp((mask),v6Unspecified)==0) && (strcmp((tag), "ra")!=0))
 
-void
-v6addroute(struct Fs *f, char *tag, uint8_t * a, uint8_t * mask,
-                  uint8_t * gate, int type)
+void v6addroute(struct Fs *f, char *tag, uint8_t *a, uint8_t *mask,
+               uint8_t *gate, int type)
 {
        struct route *p;
        uint32_t sa[IPllen], ea[IPllen];
@@ -377,24 +413,24 @@ struct route **looknode(struct route **cur, struct route *r)
                        return 0;
 
                switch (rangecompare(r, p)) {
-                       case Rcontains:
-                               return 0;
-                       case Rpreceeds:
-                               cur = &p->rt.left;
-                               break;
-                       case Rfollows:
-                               cur = &p->rt.right;
-                               break;
-                       case Rcontained:
-                               cur = &p->rt.mid;
-                               break;
-                       case Requals:
-                               return cur;
+               case Rcontains:
+                       return 0;
+               case Rpreceeds:
+                       cur = &p->rt.left;
+                       break;
+               case Rfollows:
+                       cur = &p->rt.right;
+                       break;
+               case Rcontained:
+                       cur = &p->rt.mid;
+                       break;
+               case Requals:
+                       return cur;
                }
        }
 }
 
-void v4delroute(struct Fs *f, uint8_t * a, uint8_t * mask, int dolock)
+void v4delroute(struct Fs *f, uint8_t *a, uint8_t *mask, int dolock)
 {
        struct route **r, *p;
        struct route rt;
@@ -413,9 +449,10 @@ void v4delroute(struct Fs *f, uint8_t * a, uint8_t * mask, int dolock)
                r = looknode(&f->v4root[h], &rt);
                if (r) {
                        p = *r;
-                       /* TODO: bad usage of kref (maybe use a release).  I didn't change
-                        * this one, since it looks like the if code is when we want to
-                        * release.  btw, use better code reuse btw v4 and v6... */
+                       /* TODO: bad usage of kref (maybe use a release).  I
+                        * didn't change this one, since it looks like the if
+                        * code is when we want to release.  btw, use better
+                        * code reuse btw v4 and v6... */
                        if (kref_put(&p->rt.kref)) {
                                *r = 0;
                                addqueue(&f->queue, p->rt.left);
@@ -459,9 +496,10 @@ void v6delroute(struct Fs *f, uint8_t * a, uint8_t * mask, int dolock)
                r = looknode(&f->v6root[h], &rt);
                if (r) {
                        p = *r;
-                       /* TODO: bad usage of kref (maybe use a release).  I didn't change
-                        * this one, since it looks like the if code is when we want to
-                        * release.  btw, use better code reuse btw v4 and v6... */
+                       /* TODO: bad usage of kref (maybe use a release).  I
+                        * didn't change this one, since it looks like the if
+                        * code is when we want to release.  btw, use better
+                        * code reuse btw v4 and v6... */
                        if (kref_put(&p->rt.kref)) {
                                *r = 0;
                                addqueue(&f->queue, p->rt.left);
@@ -620,9 +658,8 @@ void routetype(int type, char *p)
 
 char *rformat = "%-15I %-4M %-15I %4.4s %4.4s %3s\n";
 
-void
-convroute(struct route *r, uint8_t * addr, uint8_t * mask,
-                 uint8_t * gate, char *t, int *nifc)
+void convroute(struct route *r, uint8_t *addr, uint8_t *mask, uint8_t *gate,
+              char *t, int *nifc)
 {
        int i;
 
@@ -636,7 +673,8 @@ convroute(struct route *r, uint8_t * addr, uint8_t * mask,
        } else {
                for (i = 0; i < IPllen; i++) {
                        hnputl(addr + 4 * i, r->v6.address[i]);
-                       hnputl(mask + 4 * i, ~(r->v6.endaddress[i] ^ r->v6.address[i]));
+                       hnputl(mask + 4 * i,
+                              ~(r->v6.endaddress[i] ^ r->v6.address[i]));
                }
                memmove(gate, r->v6.gate, IPaddrlen);
        }
@@ -665,7 +703,8 @@ static void sprintroute(struct route *r, struct routewalk *rw)
                iname = ifbuf;
                snprintf(ifbuf, sizeof ifbuf, "%d", nifc);
        }
-       p = seprintf(rw->p, rw->e, rformat, addr, mask, gate, t, r->rt.tag, iname);
+       p = seprintf(rw->p, rw->e, rformat, addr, mask, gate, t, r->rt.tag,
+                    iname);
        if (rw->o < 0) {
                n = p - rw->p;
                if (n > -rw->o) {
@@ -769,7 +808,8 @@ int routeflush(struct Fs *f, struct route *r, char *tag)
        if (routeflush(f, r->rt.right, tag))
                return 1;
        if ((r->rt.type & Rifc) == 0) {
-               if (tag == NULL || strncmp(tag, r->rt.tag, sizeof(r->rt.tag)) == 0) {
+               if (tag == NULL ||
+                   strncmp(tag, r->rt.tag, sizeof(r->rt.tag)) == 0) {
                        delroute(f, r, 0);
                        return 1;
                }
@@ -777,7 +817,7 @@ int routeflush(struct Fs *f, struct route *r, char *tag)
        return 0;
 }
 
-long routewrite(struct Fs *f, struct chan *c, char *p, int n)
+long routewrite(struct Fs *f, struct chan *c, char *p, size_t n)
 {
        ERRSTACK(1);
        int h, changed;
@@ -794,7 +834,7 @@ long routewrite(struct Fs *f, struct chan *c, char *p, int n)
                nexterror();
        }
        if (cb->nf < 1)
-               error("short control request");
+               error(EINVAL, "short control request");
 
        if (strcmp(cb->f[0], "flush") == 0) {
                tag = cb->f[1];
@@ -812,7 +852,7 @@ long routewrite(struct Fs *f, struct chan *c, char *p, int n)
                        }
        } else if (strcmp(cb->f[0], "remove") == 0) {
                if (cb->nf < 3)
-                       error(Ebadarg);
+                       error(EINVAL, ERROR_FIXME);
                parseip(addr, cb->f[1]);
                parseipmask(mask, cb->f[2]);
                if (memcmp(addr, v4prefix, IPv4off) == 0)
@@ -821,7 +861,7 @@ long routewrite(struct Fs *f, struct chan *c, char *p, int n)
                        v6delroute(f, addr, mask, 1);
        } else if (strcmp(cb->f[0], "add") == 0) {
                if (cb->nf < 4)
-                       error(Ebadarg);
+                       error(EINVAL, ERROR_FIXME);
                parseip(addr, cb->f[1]);
                parseipmask(mask, cb->f[2]);
                parseip(gate, cb->f[3]);
@@ -831,13 +871,13 @@ long routewrite(struct Fs *f, struct chan *c, char *p, int n)
                        tag = a->tag;
                }
                if (memcmp(addr, v4prefix, IPv4off) == 0)
-                       v4addroute(f, tag, addr + IPv4off, mask + IPv4off, gate + IPv4off,
-                                          0);
+                       v4addroute(f, tag, addr + IPv4off, mask + IPv4off,
+                                  gate + IPv4off, 0);
                else
                        v6addroute(f, tag, addr, mask, gate, 0);
        } else if (strcmp(cb->f[0], "tag") == 0) {
                if (cb->nf < 2)
-                       error(Ebadarg);
+                       error(EINVAL, ERROR_FIXME);
 
                a = c->aux;
                na = newipaux(a->owner, cb->f[1]);