summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO19
-rw-r--r--conf/cf-lex.l18
-rw-r--r--conf/conf.c4
-rw-r--r--conf/confbase.Y2
-rw-r--r--lib/Modules2
-rw-r--r--lib/ip.h3
-rw-r--r--lib/ipv6.c349
-rw-r--r--lib/ipv6.h46
-rw-r--r--nest/config.Y13
-rw-r--r--nest/iface.c4
-rw-r--r--sysdep/cf/linux-v6.h9
-rw-r--r--sysdep/linux/netlink/netlink.c13
-rw-r--r--sysdep/unix/io.c4
13 files changed, 438 insertions, 48 deletions
diff --git a/TODO b/TODO
index d4f55e5..802c2d0 100644
--- a/TODO
+++ b/TODO
@@ -14,8 +14,7 @@ Core
- default preferences of protocols: prefer BGP over OSPF/RIP external routes?
- static: check validity of route destination?
-
-- device: configuration of interface patterns
+- static: allow specifying a per-route filter program for setting route attributes?
- rte_update: check whether all bits not covered by masklen are zero
- rte_update: debug mode
@@ -31,6 +30,7 @@ Core
- config: executable config files
- config: when parsing prefix, check zero bits
- config: reconfiguration
+- config: useless rules when protocols disabled
- krt: rescan interfaces when route addition fails?
- krt: does PERSIST mode have any sense if kernel syncer is shut down as last?
@@ -53,47 +53,41 @@ Cleanup
- replace all NUM, IPA and expr tokens by constant filter expressions
- try compiling with -Wunused
- does everybody test return value of sk_open?
+- add references to RFC's we did follow
Various ideas
~~~~~~~~~~~~~
- real multipath (doesn't seem to be simple at all :()
- fake multipath (even less simple)
- route recalculation timing and flap dampening [see RFC2439 for algorithms]
-- aggregate engine: standard route aggregation and summarization
+- aggregate engine: standard route aggregation and summarization [RFC2519]
- aggregate engine: injection of manually configured pseudo-static routes
- generate default route if any working BGP connection exists (aggregate engine again?)
- generate default route to IGP's (aggregate engine yet another time?)
+- look at RFC 2386 (QoS-based routing)
RIP
~~~
- - RIP: export-only and import-only mode?
+ - export-only and import-only mode?
- drop RIPv1 (Historic protocol)?
- Route Tag
- limit routing table xfer (frequency, only to neighbors)
- - multicast on/off (per interface)
OSPF
~~~~
- importing of device routes for networks where we don't run OSPF
- check incoming packets using neighbor cache
- - stub area: either no external routes or only default route
- RFC2328 appendix E: Use a better algorithm
- automatic generation of external route tags (RFC1403)
- RFC1587 NSSA areas
- RFC2370 opaque LSA's
- - RFC1793 Demand Circuit Support ??
- respect interface MTU and try not to create larger packets unless unavoidable
-
BGP
~~~
- - in, local, out RIB
- - maxsize=4096
- - detection of loops
- aggregation, ATOMIC_AGGREGATE
- communities
- - confederations
- attributes must be sorted!
- re-export of NEXT_HOP attribute
- BGP session over currently down interface
@@ -104,7 +98,6 @@ BGP
- inter-advertisement delay???!
- normalize (sort) incoming AS-SET's
- maximum length of AS paths
-
- expected neighbor AS
- hold time
- idle timer after error: initial value, exponential growth, maximum value
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index 94c2b2a..21727a9 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -65,9 +65,25 @@ WHITE [ \t]
%%
{DIGIT}+\.{DIGIT}+\.{DIGIT}+\.{DIGIT}+ {
+#ifdef IPV6
+ if (ipv4_pton_u32(yytext, &cf_lval.i32))
+ return RTRID;
+ cf_error("Invalid IPv4 address %s", yytext);
+#else
if (ip_pton(yytext, &cf_lval.a))
return IPA;
- cf_error("Invalid IP address");
+ cf_error("Invalid IP address %s", yytext);
+#endif
+}
+
+({XIGIT}*::|({XIGIT}*:){3,})({XIGIT}*|{DIGIT}+\.{DIGIT}+\.{DIGIT}+\.{DIGIT}+) {
+#ifdef IPV6
+ if (ip_pton(yytext, &cf_lval.a))
+ return IPA;
+ cf_error("Invalid IP address %s", yytext);
+#else
+ cf_error("This is an IPv4 router, therefore IPv6 addresses are not supported");
+#endif
}
0x{DIGIT}+ {
diff --git a/conf/conf.c b/conf/conf.c
index 0ce593c..d9bf9d8 100644
--- a/conf/conf.c
+++ b/conf/conf.c
@@ -54,6 +54,10 @@ config_parse(struct config *c)
cf_parse();
filters_postconfig(); /* FIXME: Do we really need this? */
protos_postconfig(c);
+#ifdef IPV6
+ if (!c->router_id)
+ cf_error("Router ID must be configured manually on IPv6 routers");
+#endif
return 1;
}
diff --git a/conf/confbase.Y b/conf/confbase.Y
index f9293a4..a6eb876 100644
--- a/conf/confbase.Y
+++ b/conf/confbase.Y
@@ -22,6 +22,7 @@ CF_DECLS
%union {
int i;
+ u32 i32;
ip_addr a;
struct symbol *s;
char *t;
@@ -35,6 +36,7 @@ CF_DECLS
%token END
%token <i> NUM
+%token <i32> RTRID
%token <a> IPA
%token <s> SYM
%token <t> TEXT
diff --git a/lib/Modules b/lib/Modules
index 1597b9a..cf65412 100644
--- a/lib/Modules
+++ b/lib/Modules
@@ -2,7 +2,7 @@ birdlib.h
bitops.c
bitops.h
ip.h
-#ifdef CONFIG_IPV6
+#ifdef IPV6
ipv6.c
ipv6.h
#else
diff --git a/lib/ip.h b/lib/ip.h
index 1bce89f..9b247d5 100644
--- a/lib/ip.h
+++ b/lib/ip.h
@@ -35,7 +35,8 @@
#define SCOPE_HOST 0
#define SCOPE_LINK 1
#define SCOPE_SITE 2
-#define SCOPE_UNIVERSE 3
+#define SCOPE_ORGANIZATION 3
+#define SCOPE_UNIVERSE 4
/*
* Is it a valid network prefix?
diff --git a/lib/ipv6.c b/lib/ipv6.c
index e612af7..c1b0763 100644
--- a/lib/ipv6.c
+++ b/lib/ipv6.c
@@ -1,12 +1,357 @@
/*
* BIRD Library -- IPv6 Address Manipulation Functions
*
- * (c) 1998 Martin Mares <mj@ucw.cz>
+ * (c) 1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
+ *
*/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
#include "nest/bird.h"
#include "lib/ip.h"
+#include "lib/bitops.h"
+#include "lib/endian.h"
+
+/*
+ * See RFC 2373 for explanation of IPv6 addressing issues.
+ */
+
+ip_addr
+ipv6_mkmask(unsigned n)
+{
+ ip_addr a;
+ int i;
+
+ for(i=0; i<4; i++)
+ {
+ if (!n)
+ a.addr[i] = 0;
+ else if (n >= 32)
+ {
+ a.addr[i] = ~0;
+ n -= 32;
+ }
+ else
+ {
+ a.addr[i] = u32_mkmask(n);
+ n = 0;
+ }
+ }
+ return a;
+}
+
+unsigned
+ipv6_mklen(ip_addr *a)
+{
+ int i, j, n;
+
+ for(i=0, n=0; i<4; i++, n+=32)
+ if (a->addr[i] != ~0U)
+ {
+ j = u32_masklen(a->addr[i]);
+ if (j < 0)
+ return j;
+ n += j;
+ while (++i < 4)
+ if (a->addr[i])
+ return -1;
+ break;
+ }
+ return n;
+}
+
+int
+ipv6_classify(ip_addr *a)
+{
+ u32 x = a->addr[0];
+
+ /* FIXME: Relax these requirements? */
+ if ((x & 0xe0000000) == 0x20000000) /* Aggregatable Global Unicast Address */
+ return IADDR_HOST | SCOPE_UNIVERSE;
+ if ((x & 0xfc000000) == 0xe8000000) /* Link-Local Address */
+ return IADDR_HOST | SCOPE_LINK;
+ if ((x & 0xfc000000) == 0xec000000) /* Site-Local Address */
+ return IADDR_HOST | SCOPE_SITE;
+ if ((x & 0xff000000) == 0xff000000) /* Multicast Address */
+ {
+ unsigned int scope = (x >> 16) & 0x0f;
+ switch (scope)
+ {
+ case 1: return IADDR_MULTICAST | SCOPE_HOST;
+ case 2: return IADDR_MULTICAST | SCOPE_LINK;
+ case 5: return IADDR_MULTICAST | SCOPE_SITE;
+ case 8: return IADDR_MULTICAST | SCOPE_ORGANIZATION;
+ case 14: return IADDR_MULTICAST | SCOPE_UNIVERSE;
+ }
+ }
+ return IADDR_INVALID;
+}
+
+void
+ipv6_hton(ip_addr *a)
+{
+ int i;
+
+ for(i=0; i<4; i++)
+ a->addr[i] = htonl(a->addr[i]);
+}
+
+void
+ipv6_ntoh(ip_addr *a)
+{
+ int i;
+
+ for(i=0; i<4; i++)
+ a->addr[i] = ntohl(a->addr[i]);
+}
+
+int
+ipv6_compare(ip_addr *x, ip_addr *y)
+{
+ int i;
+
+ for(i=0; i<4; i++)
+ if (x->addr[i] > y->addr[i])
+ return 1;
+ else if (x->addr[i] < y->addr[i])
+ return -1;
+ return 0;
+}
+
+/*
+ * Conversion of IPv6 address to presentation format and vice versa.
+ * Heavily inspired by routines written by Paul Vixie for the BIND project
+ * and of course by RFC 2373.
+ */
+
+char *
+ip_ntop(ip_addr a, char *b)
+{
+ u16 words[8];
+ int bestpos, bestlen, curpos, curlen, i;
+ char *c;
+
+ /* First of all, preprocess the address and find the longest run of zeros */
+ bestlen = bestpos = curpos = curlen = 0;
+ for(i=0; i<8; i++)
+ {
+ u32 x = a.addr[i/2];
+ words[i] = ((i%2) ? x : (x >> 16)) & 0xffff;
+ if (words[i])
+ curlen = 0;
+ else
+ {
+ if (!curlen)
+ curpos = i;
+ curlen++;
+ if (curlen > bestlen)
+ {
+ bestpos = curpos;
+ bestlen = curlen;
+ }
+ }
+ }
+ if (bestlen < 2)
+ bestpos = -1;
+
+ /* Is it an encapsulated IPv4 address? */
+ if (!bestpos &&
+ (bestlen == 5 && a.addr[2] == 0xffff ||
+ bestlen == 6))
+ {
+ u32 x = a.addr[3];
+ b += sprintf(b, "::%s%d.%d.%d.%d",
+ a.addr[2] ? "ffff:" : "",
+ ((x >> 24) & 0xff),
+ ((x >> 16) & 0xff),
+ ((x >> 8) & 0xff),
+ (x & 0xff));
+ return b;
+ }
+
+ /* Normal IPv6 formatting, compress the largest sequence of zeros */
+ for(i=0; i<8; i++)
+ {
+ if (i == bestpos)
+ {
+ i += bestlen - 1;
+ *b++ = ':';
+ if (i == 7)
+ *b++ = ':';
+ }
+ else
+ {
+ if (i)
+ *b++ = ':';
+ b += sprintf(b, "%x", words[i]);
+ }
+ }
+ *b = 0;
+ return b;
+}
+
+char *
+ip_ntox(ip_addr a, char *b)
+{
+ int i;
+
+ for(i=0; i<4; i++)
+ {
+ if (i)
+ *b++ = '.';
+ b += sprintf(b, "%08x", a.addr[i]);
+ }
+ return b;
+}
+
+int
+ipv4_pton_u32(char *a, u32 *o)
+{
+ int i,j;
+ unsigned long int l;
+ u32 ia = 0;
+
+ i=4;
+ while (i--)
+ {
+ char *d, *c = strchr(a, '.');
+ if (!c != !i)
+ return 0;
+ l = strtoul(a, &d, 10);
+ if (d != c && *d || l > 255)
+ return 0;
+ ia = (ia << 8) | l;
+ if (c)
+ c++;
+ a = c;
+ }
+ *o = ia;
+ return 1;
+}
+
+int
+ip_pton(char *a, ip_addr *o)
+{
+ u16 words[8];
+ int i, j, k, l, hfil;
+ char *start;
+
+ if (a[0] == ':') /* Leading :: */
+ {
+ if (a[1] != ':')
+ return 0;
+ a++;
+ }
+ hfil = -1;
+ i = 0;
+ while (*a)
+ {
+ if (*a == ':') /* :: */
+ {
+ if (hfil >= 0)
+ return 0;
+ hfil = i;
+ a++;
+ continue;
+ }
+ j = 0;
+ l = 0;
+ start = a;
+ for(;;)
+ {
+ if (*a >= '0' && *a <= '9')
+ k = *a++ - '0';
+ else if (*a >= 'A' && *a <= 'F')
+ k = *a++ - 'A' + 10;
+ else if (*a >= 'a' && *a <= 'f')
+ k = *a++ - 'a' + 10;
+ else
+ break;
+ j = (j << 4) + k;
+ if (j >= 0x10000 || ++l > 4)
+ return 0;
+ }
+ if (*a == ':' && a[1])
+ a++;
+ else if (*a == '.' && (i == 6 || i < 6 && hfil >= 0))
+ { /* Embedded IPv4 address */
+ u32 x;
+ if (!ipv4_pton_u32(start, &x))
+ return 0;
+ words[i++] = x >> 16;
+ words[i++] = x;
+ break;
+ }
+ else if (*a)
+ return 0;
+ if (i >= 8)
+ return 0;
+ words[i++] = j;
+ }
+
+ /* Replace :: with an appropriate number of zeros */
+ if (hfil >= 0)
+ {
+ j = 8 - i;
+ for(i=7; i-j >= hfil; i--)
+ words[i] = words[i-j];
+ for(; i>=hfil; i--)
+ words[i] = 0;
+ }
+
+ /* Convert the address to ip_addr format */
+ for(i=0; i<4; i++)
+ o->addr[i] = (words[2*i] << 16) | words[2*i+1];
+ return 1;
+}
+
+#ifdef TEST
+
+#include "bitops.c"
+
+static void test(char *x)
+{
+ ip_addr a;
+ char c[STD_ADDRESS_P_LENGTH+1];
+
+ printf("%-40s ", x);
+ if (!ip_pton(x, &a))
+ {
+ puts("BAD");
+ return;
+ }
+ ip_ntop(a, c);
+ printf("%-40s %04x\n", c, ipv6_classify(&a));
+}
+
+int main(void)
+{
+ puts("Positive tests:");
+ test("1:2:3:4:5:6:7:8");
+ test("dead:beef:DEAD:BEEF::f00d");
+ test("::");
+ test("::1");
+ test("1::");
+ test("::1.234.5.6");
+ test("::ffff:1.234.5.6");
+ test("::fffe:1.234.5.6");
+ test("1:2:3:4:5:6:7::8");
+ test("2080::8:800:200c:417a");
+ test("ff01::101");
+
+ puts("Negative tests:");
+ test(":::");
+ test("1:2:3:4:5:6:7:8:");
+ test("1::2::3");
+ test("::12345");
+ test("::1.2.3.4:5");
+ test(":1:2:3:4:5:6:7:8");
+ test("g:1:2:3:4:5:6:7");
+ return 0;
+}
-#error "Ought to implement these."
+#endif
diff --git a/lib/ipv6.h b/lib/ipv6.h
index 35d8e29..59005f9 100644
--- a/lib/ipv6.h
+++ b/lib/ipv6.h
@@ -1,7 +1,7 @@
/*
* BIRD -- IP Addresses et Cetera for IPv6
*
- * (c) 1998 Martin Mares <mj@ucw.cz>
+ * (c) 1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
@@ -12,11 +12,11 @@
#include <netinet/in.h>
#include <string.h>
-typedef struct ipv4_addr {
+typedef struct ipv6_addr {
u32 addr[4];
} ip_addr;
-#define _MI(a,b,c,d) ((struct ip_addr) { a, b, c, d })
+#define _MI(a,b,c,d) ((struct ipv6_addr) {{ a, b, c, d }})
#define _I0(a) ((a).addr[0])
#define _I1(a) ((a).addr[1])
#define _I2(a) ((a).addr[2])
@@ -28,38 +28,50 @@ typedef struct ipv4_addr {
#define IPA_NONE _MI(0,0,0,0)
#define ipa_equal(x,y) (!memcmp(&(x),&(y),sizeof(ip_addr)))
-#define ipa_nonzero(x) (_I0(a) || _I1(a) || _I2(a) || _I3(a))
-#define ipa_and(a,b) _MI(_I0(a) & _I0(b), \
- _I1(a) & _I1(b), \
- _I2(a) & _I2(b), \
- _I3(a) & _I3(b))
-#define ipa_or(a,b) _MI(_I0(a) | _I0(b), \
- _I1(a) | _I1(b), \
- _I2(a) | _I2(b), \
- _I3(a) | _I3(b))
-#define ipa_xor(a,b) _MI(_I0(a) ^ _I0(b), \
- _I1(a) ^ _I1(b), \
- _I2(a) ^ _I2(b), \
- _I3(a) ^ _I3(b))
-#define ipa_not(a) _MI(~_I0(a),~_I1(a),~_I2(a),~_I3(a))
+#define ipa_nonzero(x) ({ ip_addr _a=(x); (_I0(_a) || _I1(_a) || _I2(_a) || _I3(_a)); })
+#define ipa_and(x,y) ({ ip_addr _a=(x), _b=(y); \
+ _MI(_I0(_a) & _I0(_b), \
+ _I1(_a) & _I1(_b), \
+ _I2(_a) & _I2(_b), \
+ _I3(_a) & _I3(_b)); })
+#define ipa_or(x,y) ({ ip_addr _a=(x), _b=(y); \
+ _MI(_I0(_a) | _I0(_b), \
+ _I1(_a) | _I1(_b), \
+ _I2(_a) | _I2(_b), \
+ _I3(_a) | _I3(_b)); })
+#define ipa_xor(x,y) ({ ip_addr _a=(x), _b=(y); \
+ _MI(_I0(_a) ^ _I0(_b), \
+ _I1(_a) ^ _I1(_b), \
+ _I2(_a) ^ _I2(_b), \
+ _I3(_a) ^ _I3(_b)); })
+#define ipa_not(x) ({ ip_addr _a=(x); _MI(~_I0(_a),~_I1(_a),~_I2(_a),~_I3(_a)); })
#define ipa_mkmask(x) ipv6_mkmask(x)
#define ipa_mklen(x) ipv6_mklen(&(x))
#define ipa_hash(x) ipv6_hash(&(x))
#define ipa_hton(x) ipv6_hton(&(x))
#define ipa_ntoh(x) ipv6_ntoh(&(x))
#define ipa_classify(x) ipv6_classify(&(x))
+/* ipa_opposite and ipa_class_mask don't make sense with IPv6 */
+/* ipa_from_u32 and ipa_to_u32 replaced by ipa_build */
+#define ipa_build(a,b,c,d) _MI(a,b,c,d)
+#define ipa_compare(x,y) ipv6_compare(&x,&y)
ip_addr ipv6_mkmask(unsigned);
unsigned ipv6_mklen(ip_addr *);
int ipv6_classify(ip_addr *);
void ipv6_hton(ip_addr *);
void ipv6_ntoh(ip_addr *);
+int ipv6_compare(ip_addr *, ip_addr *);
+int ipv4_pton_u32(char *, u32 *);
/* FIXME: Is this hash function uniformly distributed over standard routing tables? */
static inline unsigned ipv6_hash(ip_addr *a)
{
+ /* Returns a 16-bit hash key */
u32 x = _I0(*a) ^ _I1(*a) ^ _I2(*a) ^ _I3(*a);
return (x ^ (x >> 16) ^ (x >> 8)) & 0xffff;
}
+#define IP_PREC_INTERNET_CONTROL 0 /* FIXME: What's the right value? */
+
#endif
diff --git a/nest/config.Y b/nest/config.Y
index 0c65321..dfef4e2 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -20,7 +20,7 @@ CF_KEYWORDS(ROUTER, ID, PROTOCOL, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE)
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID)
-%type <i> idval
+%type <i32> idval
%type <f> imexport
%type <r> rtable
%type <p> password_list password_begin
@@ -37,8 +37,15 @@ rtrid: ROUTER ID idval ';' {
;
idval:
- NUM
- | IPA { $$ = ipa_to_u32($1); }
+ NUM { $$ = $1; }
+ | RTRID
+ | IPA {
+#ifndef IPV6
+ $$ = ipa_to_u32($1);
+#else
+ cf_error("Router IDs must be entered as hexadecimal numbers in IPv6 version");
+#endif
+ }
;
/* Creation of routing tables */
diff --git a/nest/iface.c b/nest/iface.c
index 3a5d9c6..debec45 100644
--- a/nest/iface.c
+++ b/nest/iface.c
@@ -549,8 +549,9 @@ ifa_delete(struct ifa *a)
}
static void
-auto_router_id(void) /* FIXME: What if we run IPv6??? */
+auto_router_id(void)
{
+#ifndef IPV6
struct iface *i, *j;
j = NULL;
@@ -564,6 +565,7 @@ auto_router_id(void) /* FIXME: What if we run IPv6??? */
die("Cannot determine router ID (no suitable network interface found), please configure it manually");
debug("Guessed router ID %I (%s)\n", j->addr->ip, j->name);
config->router_id = ipa_to_u32(j->addr->ip);
+#endif
}
void
diff --git a/sysdep/cf/linux-v6.h b/sysdep/cf/linux-v6.h
index 69ab0f8..ef52ee4 100644
--- a/sysdep/cf/linux-v6.h
+++ b/sysdep/cf/linux-v6.h
@@ -8,9 +8,16 @@
#define IPV6
-#define CONFIG_TOS
#define CONFIG_AUTO_ROUTES
#define CONFIG_ALL_MULTICAST
+#define CONFIG_SELF_CONSCIOUS
+
+/*
+ * Netlink supports multiple tables, but kernel IPv6 code doesn't, so we
+ * treat it as a multiple table system with number of tables set to 1.
+ */
+#define CONFIG_MULTIPLE_TABLES
+#define CONFIG_ALL_TABLES_AT_ONCE
/*
Link: sysdep/linux/netlink
diff --git a/sysdep/linux/netlink/netlink.c b/sysdep/linux/netlink/netlink.c
index 6682dbc..f71f1f5 100644
--- a/sysdep/linux/netlink/netlink.c
+++ b/sysdep/linux/netlink/netlink.c
@@ -242,7 +242,7 @@ nl_add_attr_ipa(struct nlmsghdr *h, unsigned maxsize, int code, ip_addr ipa)
a = (struct rtattr *)((char *)h + NLMSG_ALIGN(h->nlmsg_len));
a->rta_type = code;
a->rta_len = len;
- ipa = ipa_hton(ipa);
+ ipa_hton(ipa);
memcpy(RTA_DATA(a), &ipa, sizeof(ipa));
h->nlmsg_len = NLMSG_ALIGN(h->nlmsg_len) + len;
}
@@ -351,17 +351,18 @@ nl_parse_addr(struct nlmsghdr *h)
if (i->ifa_flags & IFA_F_SECONDARY)
ifa.flags |= IA_SECONDARY;
memcpy(&ifa.ip, RTA_DATA(a[IFA_LOCAL]), sizeof(ifa.ip));
- ifa.ip = ipa_ntoh(ifa.ip);
+ ipa_ntoh(ifa.ip);
ifa.pxlen = i->ifa_prefixlen;
if (ifi->flags & IF_UNNUMBERED)
{
memcpy(&ifa.opposite, RTA_DATA(a[IFA_ADDRESS]), sizeof(ifa.opposite));
- ifa.opposite = ifa.brd = ipa_ntoh(ifa.opposite);
+ ipa_ntoh(ifa.opposite);
+ ifa.brd = ifa.opposite;
}
else if ((ifi->flags & IF_BROADCAST) && a[IFA_BROADCAST])
{
memcpy(&ifa.brd, RTA_DATA(a[IFA_BROADCAST]), sizeof(ifa.brd));
- ifa.brd = ipa_ntoh(ifa.brd);
+ ipa_ntoh(ifa.brd);
}
/* else a NBMA link */
ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(ifa.pxlen));
@@ -575,7 +576,7 @@ nl_parse_route(struct nlmsghdr *h, int scan)
if (a[RTA_DST])
{
memcpy(&dst, RTA_DATA(a[RTA_DST]), sizeof(dst));
- dst = ipa_ntoh(dst);
+ ipa_ntoh(dst);
}
else
dst = IPA_NONE;
@@ -630,7 +631,7 @@ nl_parse_route(struct nlmsghdr *h, int scan)
neighbor *ng;
ra.dest = RTD_ROUTER;
memcpy(&ra.gw, RTA_DATA(a[RTA_GATEWAY]), sizeof(ra.gw));
- ra.gw = ipa_ntoh(ra.gw);
+ ipa_ntoh(ra.gw);
ng = neigh_find(&p->p, &ra.gw, 0);
if (ng)
ra.iface = ng->iface;
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index 39cf200..3e070fa 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -314,7 +314,7 @@ sk_new(pool *p)
static inline void
set_inaddr(struct in_addr *ia, ip_addr a)
{
- a = ipa_hton(a);
+ ipa_hton(a);
memcpy(&ia->s_addr, &a, sizeof(a));
}
@@ -334,7 +334,7 @@ get_sockaddr(struct sockaddr_in *sa, ip_addr *a, unsigned *port)
if (port)
*port = ntohs(sa->sin_port);
memcpy(a, &sa->sin_addr.s_addr, sizeof(*a));
- *a = ipa_ntoh(*a);
+ ipa_ntoh(*a);
}
static char *