chiark / gitweb /
integer arithmetic types: correct perhaps-possible negative timeout situation
[secnet.git] / netlink.c
index 704dcf6d35a2287f1ccdf041abcc05b1243bcdfa..70eb9283b080104e37131d65170cdd7581988988 100644 (file)
--- a/netlink.c
+++ b/netlink.c
@@ -97,6 +97,9 @@ their use.
 
 */
 
+#include <string.h>
+#include <assert.h>
+#include <limits.h>
 #include "secnet.h"
 #include "util.h"
 #include "ipaddr.h"
@@ -147,30 +150,30 @@ static inline uint16_t ip_csum(uint8_t *iph,uint32_t count)
 static inline uint16_t ip_fast_csum(uint8_t *iph, uint32_t ihl) {
     uint32_t sum;
 
-    __asm__ __volatile__("
-            movl (%1), %0
-            subl $4, %2
-            jbe 2f
-            addl 4(%1), %0
-            adcl 8(%1), %0
-            adcl 12(%1), %0
-1:          adcl 16(%1), %0
-            lea 4(%1), %1
-            decl %2
-            jne 1b
-            adcl $0, %0
-            movl %0, %2
-            shrl $16, %0
-            addw %w2, %w0
-            adcl $0, %0
-            notl %0
-2:
-            "
+    __asm__ __volatile__(
+            "movl (%1), %0      ;\n"
+            "subl $4, %2        ;\n"
+            "jbe 2f             ;\n"
+            "addl 4(%1), %0     ;\n"
+            "adcl 8(%1), %0     ;\n"
+            "adcl 12(%1), %0    ;\n"
+"1:         adcl 16(%1), %0     ;\n"
+            "lea 4(%1), %1      ;\n"
+            "decl %2            ;\n"
+            "jne 1b             ;\n"
+            "adcl $0, %0        ;\n"
+            "movl %0, %2        ;\n"
+            "shrl $16, %0       ;\n"
+            "addw %w2, %w0      ;\n"
+            "adcl $0, %0        ;\n"
+            "notl %0            ;\n"
+"2:                             ;\n"
         /* Since the input registers which are loaded with iph and ipl
            are modified, we must also specify them as outputs, or gcc
            will assume they contain their original values. */
         : "=r" (sum), "=r" (iph), "=r" (ihl)
-        : "1" (iph), "2" (ihl));
+        : "1" (iph), "2" (ihl)
+       : "memory");
     return sum;
 }
 #else
@@ -414,7 +417,7 @@ static void netlink_packet_deliver(struct netlink *st,
     BUF_ASSERT_USED(buf);
 
     if (dest==st->secnet_address) {
-       Message(M_ERR,"%s: trying to deliver a packet to myself!\n");
+       Message(M_ERR,"%s: trying to deliver a packet to myself!\n",st->name);
        BUF_FREE(buf);
        return;
     }
@@ -497,18 +500,19 @@ static void netlink_packet_deliver(struct netlink *st,
            netlink_icmp_simple(st,buf,client,ICMP_TYPE_UNREACHABLE,
                                ICMP_CODE_NET_PROHIBITED);
            BUF_FREE(buf);
-       }
-       if (best_quality>0) {
-           /* XXX Fragment if required */
-           st->routes[best_match]->deliver(
-               st->routes[best_match]->dst, buf);
-           st->routes[best_match]->outcount++;
-           BUF_ASSERT_FREE(buf);
        } else {
-           /* Generate ICMP destination unreachable */
-           netlink_icmp_simple(st,buf,client,ICMP_TYPE_UNREACHABLE,
-                               ICMP_CODE_NET_UNREACHABLE); /* client==NULL */
-           BUF_FREE(buf);
+           if (best_quality>0) {
+               /* XXX Fragment if required */
+               st->routes[best_match]->deliver(
+                   st->routes[best_match]->dst, buf);
+               st->routes[best_match]->outcount++;
+               BUF_ASSERT_FREE(buf);
+           } else {
+               /* Generate ICMP destination unreachable */
+               netlink_icmp_simple(st,buf,client,ICMP_TYPE_UNREACHABLE,
+                                   ICMP_CODE_NET_UNREACHABLE); /* client==NULL */
+               BUF_FREE(buf);
+           }
        }
     }
     BUF_ASSERT_FREE(buf);
@@ -720,14 +724,15 @@ static void netlink_dump_routes(struct netlink *st, bool_t requested)
        for (i=0; i<st->n_clients; i++) {
            netlink_output_subnets(st,c,st->routes[i]->subnets);
            Message(c,"-> tunnel %s (%s,mtu %d,%s routes,%s,"
-                   "quality %d,use %d)\n",
+                   "quality %d,use %d,pri %lu)\n",
                    st->routes[i]->name,
                    st->routes[i]->up?"up":"down",
                    st->routes[i]->mtu,
                    st->routes[i]->options&OPT_SOFTROUTE?"soft":"hard",
                    st->routes[i]->options&OPT_ALLOWROUTE?"free":"restricted",
                    st->routes[i]->link_quality,
-                   st->routes[i]->outcount);
+                   st->routes[i]->outcount,
+                   (unsigned long)st->routes[i]->priority);
        }
        net=ipaddr_to_string(st->secnet_address);
        Message(c,"%s/32 -> netlink \"%s\" (use %d)\n",
@@ -763,12 +768,14 @@ static void netlink_phase_hook(void *sst, uint32_t new_phase)
     /* All the networks serviced by the various tunnels should now
      * have been registered.  We build a routing table by sorting the
      * clients by priority.  */
-    st->routes=safe_malloc(st->n_clients*sizeof(*st->routes),
-                          "netlink_phase_hook");
+    st->routes=safe_malloc_ary(sizeof(*st->routes),st->n_clients,
+                              "netlink_phase_hook");
     /* Fill the table */
     i=0;
-    for (c=st->clients; c; c=c->next)
+    for (c=st->clients; c; c=c->next) {
+       assert(i<INT_MAX);
        st->routes[i++]=c;
+    }
     /* Sort the table in descending order of priority */
     qsort(st->routes,st->n_clients,sizeof(*st->routes),
          netlink_compare_client_priority);
@@ -908,6 +915,7 @@ static closure_t *netlink_inst_create(struct netlink *st,
     c->kup=False;
     c->next=st->clients;
     st->clients=c;
+    assert(st->n_clients < INT_MAX);
     st->n_clients++;
 
     return &c->cl;
@@ -935,7 +943,7 @@ static list_t *netlink_inst_apply(closure_t *self, struct cloc loc,
 
 netlink_deliver_fn *netlink_init(struct netlink *st,
                                 void *dst, struct cloc loc,
-                                dict_t *dict, string_t description,
+                                dict_t *dict, cstring_t description,
                                 netlink_route_fn *set_routes,
                                 netlink_deliver_fn *to_host)
 {
@@ -961,9 +969,10 @@ netlink_deliver_fn *netlink_init(struct netlink *st,
     if (l) 
        st->networks=string_list_to_ipset(l,loc,st->name,"networks");
     else {
-       Message(M_WARNING,"%s: no local networks (parameter \"networks\") "
-               "defined\n",st->name);
-       st->networks=ipset_new();
+       struct ipset *empty;
+       empty=ipset_new();
+       st->networks=ipset_complement(empty);
+       ipset_free(empty);
     }
     l=dict_lookup(dict,"remote-networks");
     if (l) {
@@ -1063,7 +1072,6 @@ static list_t *null_apply(closure_t *self, struct cloc loc, dict_t *context,
     return new_closure(&st->nl.cl);
 }
 
-init_module netlink_module;
 void netlink_module(dict_t *dict)
 {
     add_closure(dict,"null-netlink",null_apply);