Temporary OSPFv3 development commit
This commit is contained in:
parent
b49e6f5a65
commit
061ab802a6
11 changed files with 162 additions and 83 deletions
54
lib/ipv6.c
54
lib/ipv6.c
|
@ -136,60 +136,6 @@ ipv6_compare(ip_addr X, ip_addr Y)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* From Linux include/net/ipv6.h */
|
|
||||||
#define NEXTHDR_HOP 0 /* Hop-by-hop option header. */
|
|
||||||
#define NEXTHDR_ROUTING 43 /* Routing header. */
|
|
||||||
#define NEXTHDR_FRAGMENT 44 /* Fragmentation/reassembly header. */
|
|
||||||
#define NEXTHDR_DEST 60 /* Destination options header. */
|
|
||||||
#define NEXTHDR_NONE 59 /* No next header */
|
|
||||||
|
|
||||||
#define NEXTHDR_ESP 50 /* Encapsulating security payload. */
|
|
||||||
#define NEXTHDR_AUTH 51 /* Authentication header. */
|
|
||||||
|
|
||||||
|
|
||||||
byte *
|
|
||||||
ipv6_skip_header(byte *pkt, int *len)
|
|
||||||
{
|
|
||||||
int l = *len;
|
|
||||||
int q;
|
|
||||||
u8 nh;
|
|
||||||
|
|
||||||
if (l < 40 || (*pkt & 0xf0) != 0x60)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Skip IPv6 header */
|
|
||||||
nh = pkt[6];
|
|
||||||
pkt += 40;
|
|
||||||
|
|
||||||
while ()
|
|
||||||
{
|
|
||||||
switch (nw)
|
|
||||||
{
|
|
||||||
case NEXTHDR_FRAGMENT:
|
|
||||||
|
|
||||||
case NEXTHDR_HOP:
|
|
||||||
case NEXTHDR_ROUTING:
|
|
||||||
case NEXTHDR_DEST:
|
|
||||||
|
|
||||||
case NEXTHDR_AUTH:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NEXTHDR_NONE:
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return pkt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
q = (*pkt & 0x0f) * 4;
|
|
||||||
if (q > l)
|
|
||||||
return NULL;
|
|
||||||
*len -= q;
|
|
||||||
return pkt + q;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Conversion of IPv6 address to presentation format and vice versa.
|
* Conversion of IPv6 address to presentation format and vice versa.
|
||||||
* Heavily inspired by routines written by Paul Vixie for the BIND project
|
* Heavily inspired by routines written by Paul Vixie for the BIND project
|
||||||
|
|
|
@ -69,6 +69,9 @@ typedef struct ipv6_addr {
|
||||||
#define ipa_getbit(x, y) ipv6_getbit(x, y)
|
#define ipa_getbit(x, y) ipv6_getbit(x, y)
|
||||||
#define ipa_absolutize(x,y) ipv6_absolutize(x,y)
|
#define ipa_absolutize(x,y) ipv6_absolutize(x,y)
|
||||||
|
|
||||||
|
/* In IPv6, SOCK_RAW does not return packet header */
|
||||||
|
#define ip_skip_header(x, y) x
|
||||||
|
|
||||||
ip_addr ipv6_mkmask(unsigned);
|
ip_addr ipv6_mkmask(unsigned);
|
||||||
unsigned ipv6_mklen(ip_addr *);
|
unsigned ipv6_mklen(ip_addr *);
|
||||||
int ipv6_classify(ip_addr *);
|
int ipv6_classify(ip_addr *);
|
||||||
|
|
|
@ -102,6 +102,12 @@ if_connected(ip_addr *a, struct iface *i) /* -1=error, 1=match, 0=no match */
|
||||||
|
|
||||||
neighbor *
|
neighbor *
|
||||||
neigh_find(struct proto *p, ip_addr *a, unsigned flags)
|
neigh_find(struct proto *p, ip_addr *a, unsigned flags)
|
||||||
|
{
|
||||||
|
return neigh_find2(p, a, NULL, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
neighbor *
|
||||||
|
neigh_find2(struct proto *p, ip_addr *a, unsigned flags)
|
||||||
{
|
{
|
||||||
neighbor *n;
|
neighbor *n;
|
||||||
int class, scope = SCOPE_HOST;
|
int class, scope = SCOPE_HOST;
|
||||||
|
|
|
@ -67,7 +67,13 @@ ospf_open_ip_socket(struct ospf_iface *ifa)
|
||||||
ipsk = sk_new(p->pool);
|
ipsk = sk_new(p->pool);
|
||||||
ipsk->type = SK_IP;
|
ipsk->type = SK_IP;
|
||||||
ipsk->dport = OSPF_PROTO;
|
ipsk->dport = OSPF_PROTO;
|
||||||
|
|
||||||
|
#ifdef OSPFv2
|
||||||
ipsk->saddr = ifa->iface->addr->ip;
|
ipsk->saddr = ifa->iface->addr->ip;
|
||||||
|
#else /* OSPFv3 */
|
||||||
|
ipsk->saddr = ifa->lladdr;
|
||||||
|
#endif
|
||||||
|
|
||||||
ipsk->tos = IP_PREC_INTERNET_CONTROL;
|
ipsk->tos = IP_PREC_INTERNET_CONTROL;
|
||||||
ipsk->ttl = 1;
|
ipsk->ttl = 1;
|
||||||
if (ifa->type == OSPF_IT_VLINK)
|
if (ifa->type == OSPF_IT_VLINK)
|
||||||
|
@ -135,7 +141,13 @@ ospf_iface_chstate(struct ospf_iface *ifa, u8 state)
|
||||||
ifa->dr_sk->type = SK_IP_MC;
|
ifa->dr_sk->type = SK_IP_MC;
|
||||||
ifa->dr_sk->sport = 0;
|
ifa->dr_sk->sport = 0;
|
||||||
ifa->dr_sk->dport = OSPF_PROTO;
|
ifa->dr_sk->dport = OSPF_PROTO;
|
||||||
|
|
||||||
|
#ifdef OSPFv2
|
||||||
ifa->dr_sk->saddr = AllDRouters;
|
ifa->dr_sk->saddr = AllDRouters;
|
||||||
|
#else /* OSPFv3 */
|
||||||
|
ifa->dr_sk->saddr = ifa->lladdr;
|
||||||
|
#endif
|
||||||
|
|
||||||
ifa->dr_sk->daddr = AllDRouters;
|
ifa->dr_sk->daddr = AllDRouters;
|
||||||
ifa->dr_sk->tos = IP_PREC_INTERNET_CONTROL;
|
ifa->dr_sk->tos = IP_PREC_INTERNET_CONTROL;
|
||||||
ifa->dr_sk->ttl = 1;
|
ifa->dr_sk->ttl = 1;
|
||||||
|
@ -308,7 +320,13 @@ ospf_open_mc_socket(struct ospf_iface *ifa)
|
||||||
mcsk->type = SK_IP_MC;
|
mcsk->type = SK_IP_MC;
|
||||||
mcsk->sport = 0;
|
mcsk->sport = 0;
|
||||||
mcsk->dport = OSPF_PROTO;
|
mcsk->dport = OSPF_PROTO;
|
||||||
mcsk->saddr = AllSPFRouters;
|
|
||||||
|
#ifdef OSPFv2
|
||||||
|
mcsk->saddr = AllDRouters;
|
||||||
|
#else /* OSPFv3 */
|
||||||
|
mcsk->saddr = ifa->lladdr;
|
||||||
|
#endif
|
||||||
|
|
||||||
mcsk->daddr = AllSPFRouters;
|
mcsk->daddr = AllSPFRouters;
|
||||||
mcsk->tos = IP_PREC_INTERNET_CONTROL;
|
mcsk->tos = IP_PREC_INTERNET_CONTROL;
|
||||||
mcsk->ttl = 1;
|
mcsk->ttl = 1;
|
||||||
|
|
|
@ -99,7 +99,7 @@ htonlsah(struct ospf_lsa_header *h, struct ospf_lsa_header *n)
|
||||||
#ifdef OSPFv2
|
#ifdef OSPFv2
|
||||||
n->options = h->options;
|
n->options = h->options;
|
||||||
#endif
|
#endif
|
||||||
n->type = h->type;
|
n->type = htont(h->type);
|
||||||
n->id = htonl(h->id);
|
n->id = htonl(h->id);
|
||||||
n->rt = htonl(h->rt);
|
n->rt = htonl(h->rt);
|
||||||
n->sn = htonl(h->sn);
|
n->sn = htonl(h->sn);
|
||||||
|
@ -114,7 +114,7 @@ ntohlsah(struct ospf_lsa_header *n, struct ospf_lsa_header *h)
|
||||||
#ifdef OSPFv2
|
#ifdef OSPFv2
|
||||||
h->options = n->options;
|
h->options = n->options;
|
||||||
#endif
|
#endif
|
||||||
h->type = n->type;
|
h->type = ntoht(n->type);
|
||||||
h->id = ntohl(n->id);
|
h->id = ntohl(n->id);
|
||||||
h->rt = ntohl(n->rt);
|
h->rt = ntohl(n->rt);
|
||||||
h->sn = ntohl(n->sn);
|
h->sn = ntohl(n->sn);
|
||||||
|
@ -143,7 +143,7 @@ htonlsab(void *h, void *n, u16 type, u16 len)
|
||||||
nrt->links = htons(hrt->links);
|
nrt->links = htons(hrt->links);
|
||||||
links = hrt->links;
|
links = hrt->links;
|
||||||
#else /* OSPFv3 */
|
#else /* OSPFv3 */
|
||||||
hrt->options = htonl(nrt->options);
|
nrt->options = htonl(hrt->options);
|
||||||
links = (len - sizeof(struct ospf_lsa_rt)) /
|
links = (len - sizeof(struct ospf_lsa_rt)) /
|
||||||
sizeof(struct ospf_lsa_rt_link);
|
sizeof(struct ospf_lsa_rt_link);
|
||||||
#endif
|
#endif
|
||||||
|
@ -173,6 +173,10 @@ htonlsab(void *h, void *n, u16 type, u16 len)
|
||||||
case LSA_T_SUM_NET:
|
case LSA_T_SUM_NET:
|
||||||
case LSA_T_SUM_RT:
|
case LSA_T_SUM_RT:
|
||||||
case LSA_T_EXT:
|
case LSA_T_EXT:
|
||||||
|
#ifdef OSPFv3
|
||||||
|
case LSA_T_LINK:
|
||||||
|
case LSA_T_PREFIX:
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
u32 *hid, *nid;
|
u32 *hid, *nid;
|
||||||
|
|
||||||
|
@ -241,6 +245,10 @@ ntohlsab(void *n, void *h, u16 type, u16 len)
|
||||||
case LSA_T_SUM_NET:
|
case LSA_T_SUM_NET:
|
||||||
case LSA_T_SUM_RT:
|
case LSA_T_SUM_RT:
|
||||||
case LSA_T_EXT:
|
case LSA_T_EXT:
|
||||||
|
#ifdef OSPFv3
|
||||||
|
case LSA_T_LINK:
|
||||||
|
case LSA_T_PREFIX:
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
u32 *hid, *nid;
|
u32 *hid, *nid;
|
||||||
|
|
||||||
|
@ -258,6 +266,35 @@ ntohlsab(void *n, void *h, u16 type, u16 len)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
buf_dump(const char *hdr, const byte *buf, int blen)
|
||||||
|
{
|
||||||
|
char b2[1024];
|
||||||
|
char *bp;
|
||||||
|
int first = 1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
const char *lhdr = hdr;
|
||||||
|
|
||||||
|
bp = b2;
|
||||||
|
for(i = 0; i < blen; i++)
|
||||||
|
{
|
||||||
|
if ((i > 0) && ((i % 16) == 0))
|
||||||
|
{
|
||||||
|
*bp = 0;
|
||||||
|
log(L_WARN "%s\t%s", lhdr, b2);
|
||||||
|
lhdr = "";
|
||||||
|
bp = b2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bp += snprintf(bp, 1022, "%02x ", buf[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*bp = 0;
|
||||||
|
log(L_WARN "%s\t%s", lhdr, b2);
|
||||||
|
}
|
||||||
|
|
||||||
#define MODX 4102 /* larges signed value without overflow */
|
#define MODX 4102 /* larges signed value without overflow */
|
||||||
|
|
||||||
/* Fletcher Checksum -- Refer to RFC1008. */
|
/* Fletcher Checksum -- Refer to RFC1008. */
|
||||||
|
@ -268,17 +305,25 @@ ntohlsab(void *n, void *h, u16 type, u16 len)
|
||||||
void
|
void
|
||||||
lsasum_calculate(struct ospf_lsa_header *h, void *body)
|
lsasum_calculate(struct ospf_lsa_header *h, void *body)
|
||||||
{
|
{
|
||||||
u16 length;
|
u16 length = h->length;
|
||||||
|
u16 type = h->type;
|
||||||
length = h->length;
|
|
||||||
|
|
||||||
|
log(L_WARN "Checksum %R %R %d start (len %d)", h->id, h->rt, h->type, length);
|
||||||
htonlsah(h, h);
|
htonlsah(h, h);
|
||||||
htonlsab(body, body, h->type, length - sizeof(struct ospf_lsa_header));
|
|
||||||
|
htonlsab(body, body, type, length - sizeof(struct ospf_lsa_header));
|
||||||
|
|
||||||
|
char buf[1024];
|
||||||
|
memcpy(buf, h, sizeof(struct ospf_lsa_header));
|
||||||
|
memcpy(buf + sizeof(struct ospf_lsa_header), body, length - sizeof(struct ospf_lsa_header));
|
||||||
|
buf_dump("CALC", buf, length);
|
||||||
|
|
||||||
(void) lsasum_check(h, body);
|
(void) lsasum_check(h, body);
|
||||||
|
|
||||||
|
log(L_WARN "Checksum result %4x", h->checksum);
|
||||||
|
|
||||||
ntohlsah(h, h);
|
ntohlsah(h, h);
|
||||||
ntohlsab(body, body, h->type, length - sizeof(struct ospf_lsa_header));
|
ntohlsab(body, body, type, length - sizeof(struct ospf_lsa_header));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -294,7 +339,7 @@ lsasum_check(struct ospf_lsa_header *h, void *body)
|
||||||
u16 length;
|
u16 length;
|
||||||
|
|
||||||
b = body;
|
b = body;
|
||||||
sp = (char *) &h;
|
sp = (char *) h;
|
||||||
sp += 2; /* Skip Age field */
|
sp += 2; /* Skip Age field */
|
||||||
length = ntohs(h->length) - 2;
|
length = ntohs(h->length) - 2;
|
||||||
h->checksum = 0;
|
h->checksum = 0;
|
||||||
|
|
|
@ -78,13 +78,32 @@ ospf_lsa_flooding_allowed(struct ospf_lsa_header *lsa, u32 domain, struct ospf_i
|
||||||
|
|
||||||
#else /* OSPFv3 */
|
#else /* OSPFv3 */
|
||||||
|
|
||||||
|
static int
|
||||||
|
unknown_lsa_type(struct ospf_lsa_header *lsa)
|
||||||
|
{
|
||||||
|
switch (lsa->type)
|
||||||
|
{
|
||||||
|
case LSA_T_RT:
|
||||||
|
case LSA_T_NET:
|
||||||
|
case LSA_T_SUM_NET:
|
||||||
|
case LSA_T_SUM_RT:
|
||||||
|
case LSA_T_EXT:
|
||||||
|
case LSA_T_LINK:
|
||||||
|
case LSA_T_PREFIX:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ospf_lsa_flooding_allowed(struct ospf_lsa_header *lsa, u32 domain, struct ospf_iface *ifa)
|
ospf_lsa_flooding_allowed(struct ospf_lsa_header *lsa, u32 domain, struct ospf_iface *ifa)
|
||||||
{
|
{
|
||||||
u32 scope = LSA_SCOPE(lsa);
|
u32 scope = LSA_SCOPE(lsa);
|
||||||
|
|
||||||
/* 4.5.2 (Case 2) */
|
/* 4.5.2 (Case 2) */
|
||||||
if (unknown_type(lsa) && !(lsa->type & LSA_UBIT))
|
if (unknown_lsa_type(lsa) && !(lsa->type & LSA_UBIT))
|
||||||
scope = LSA_SCOPE_LINK;
|
scope = LSA_SCOPE_LINK;
|
||||||
|
|
||||||
switch (scope)
|
switch (scope)
|
||||||
|
@ -444,9 +463,11 @@ ospf_lsupd_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
|
||||||
|
|
||||||
/* pg 143 (1) */
|
/* pg 143 (1) */
|
||||||
chsum = lsa->checksum;
|
chsum = lsa->checksum;
|
||||||
|
log(L_WARN "Checking rcv %R %R %d (len %d)", ntohl(lsa->id), ntohl(lsa->rt), ntoht(lsa->type), ntohs(lsa->length));
|
||||||
|
buf_dump("RCV", lsa, ntohs(lsa->length));
|
||||||
if (chsum != lsasum_check(lsa, NULL))
|
if (chsum != lsasum_check(lsa, NULL))
|
||||||
{
|
{
|
||||||
log(L_WARN "Received bad lsa checksum from %I", n->ip);
|
log(L_WARN "Received bad lsa checksum from %I: %x %x", n->ip, chsum, lsa->checksum);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -451,12 +451,13 @@ bdr_election(struct ospf_iface *ifa)
|
||||||
me.state = NEIGHBOR_2WAY;
|
me.state = NEIGHBOR_2WAY;
|
||||||
me.rid = myid;
|
me.rid = myid;
|
||||||
me.priority = ifa->priority;
|
me.priority = ifa->priority;
|
||||||
me.ip = ifa->iface->addr->ip;
|
|
||||||
|
|
||||||
#ifdef OSPFv2
|
#ifdef OSPFv2
|
||||||
|
me.ip = ifa->iface->addr->ip;
|
||||||
me.dr = ipa_to_u32(ifa->drip);
|
me.dr = ipa_to_u32(ifa->drip);
|
||||||
me.bdr = ipa_to_u32(ifa->bdrip);
|
me.bdr = ipa_to_u32(ifa->bdrip);
|
||||||
#else /* OSPFv3 */
|
#else /* OSPFv3 */
|
||||||
|
me.ip = ifa->lladdr;
|
||||||
me.dr = ifa->drid;
|
me.dr = ifa->drid;
|
||||||
me.bdr = ifa->bdrid;
|
me.bdr = ifa->bdrid;
|
||||||
me.iface_id = ifa->iface->index;
|
me.iface_id = ifa->iface->index;
|
||||||
|
|
|
@ -424,6 +424,10 @@ struct ospf_lsa_ext
|
||||||
|
|
||||||
#define LSA_EXT_EBIT 0x80000000
|
#define LSA_EXT_EBIT 0x80000000
|
||||||
|
|
||||||
|
/* Endianity swap for lsa->type */
|
||||||
|
#define ntoht(x) x
|
||||||
|
#define htont(x) x
|
||||||
|
|
||||||
|
|
||||||
#else /* OSPFv3 */
|
#else /* OSPFv3 */
|
||||||
|
|
||||||
|
@ -488,6 +492,10 @@ struct ospf_lsa_prefix
|
||||||
#define LSA_EXT_FBIT 0x2000000
|
#define LSA_EXT_FBIT 0x2000000
|
||||||
#define LSA_EXT_TBIT 0x1000000
|
#define LSA_EXT_TBIT 0x1000000
|
||||||
|
|
||||||
|
/* Endianity swap for lsa->type */
|
||||||
|
#define ntoht(x) ntohs(x)
|
||||||
|
#define htont(x) htons(x)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define METRIC_MASK 0x00FFFFFF
|
#define METRIC_MASK 0x00FFFFFF
|
||||||
|
|
|
@ -312,7 +312,7 @@ ospf_rt_spfa(struct ospf_area *oa)
|
||||||
nf.ar = act;
|
nf.ar = act;
|
||||||
nf.nh = act->nh;
|
nf.nh = act->nh;
|
||||||
nf.ifa = act->nhi;
|
nf.ifa = act->nhi;
|
||||||
ri_install(po, ipa_from_rid(act->lsa.rt), 32, ORT_ROUTER, &nf, NULL);
|
ri_install(po, ipa_from_rid(act->lsa.rt), MAX_PREFIX_LENGTH, ORT_ROUTER, &nf, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
rr = (struct ospf_lsa_rt_link *) (rt + 1);
|
rr = (struct ospf_lsa_rt_link *) (rt + 1);
|
||||||
|
@ -582,7 +582,7 @@ ospf_rt_sum_tr(struct ospf_area *oa)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ip = ipa_from_rid(dst_rid);
|
ip = ipa_from_rid(dst_rid);
|
||||||
pxlen = 32;
|
pxlen = MAX_PREFIX_LENGTH;
|
||||||
metric = ls->metric & METRIC_MASK;
|
metric = ls->metric & METRIC_MASK;
|
||||||
options |= ORTA_ASBR;
|
options |= ORTA_ASBR;
|
||||||
type = ORT_ROUTER;
|
type = ORT_ROUTER;
|
||||||
|
@ -595,7 +595,7 @@ ospf_rt_sum_tr(struct ospf_area *oa)
|
||||||
|
|
||||||
abrip = ipa_from_rid(en->lsa.rt);
|
abrip = ipa_from_rid(en->lsa.rt);
|
||||||
|
|
||||||
abr = fib_find(&oa->rtr, &abrip, 32);
|
abr = fib_find(&oa->rtr, &abrip, MAX_PREFIX_LENGTH);
|
||||||
if (!abr) continue;
|
if (!abr) continue;
|
||||||
|
|
||||||
nf.type = re->n.type;
|
nf.type = re->n.type;
|
||||||
|
@ -691,7 +691,7 @@ ospf_rt_sum(struct ospf_area *oa)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ip = ipa_from_rid(dst_rid);
|
ip = ipa_from_rid(dst_rid);
|
||||||
pxlen = 32;
|
pxlen = MAX_PREFIX_LENGTH;
|
||||||
metric = ls->metric & METRIC_MASK;
|
metric = ls->metric & METRIC_MASK;
|
||||||
options |= ORTA_ASBR;
|
options |= ORTA_ASBR;
|
||||||
type = ORT_ROUTER;
|
type = ORT_ROUTER;
|
||||||
|
@ -703,7 +703,7 @@ ospf_rt_sum(struct ospf_area *oa)
|
||||||
|
|
||||||
/* Page 169 (4) */
|
/* Page 169 (4) */
|
||||||
abrip = ipa_from_rid(en->lsa.rt);
|
abrip = ipa_from_rid(en->lsa.rt);
|
||||||
if (!(abr = (ort *) fib_find(&oa->rtr, &abrip, 32))) continue;
|
if (!(abr = (ort *) fib_find(&oa->rtr, &abrip, MAX_PREFIX_LENGTH))) continue;
|
||||||
if (abr->n.metric1 == LSINFINITY) continue;
|
if (abr->n.metric1 == LSINFINITY) continue;
|
||||||
if (!(abr->n.options & ORTA_ABR)) continue;
|
if (!(abr->n.options & ORTA_ABR)) continue;
|
||||||
|
|
||||||
|
@ -891,7 +891,7 @@ ospf_ext_spf(struct proto_ospf *po)
|
||||||
nf1 = NULL;
|
nf1 = NULL;
|
||||||
WALK_LIST(atmp, po->area_list)
|
WALK_LIST(atmp, po->area_list)
|
||||||
{
|
{
|
||||||
nfh = fib_find(&atmp->rtr, &rtid, 32);
|
nfh = fib_find(&atmp->rtr, &rtid, MAX_PREFIX_LENGTH);
|
||||||
if (nfh == NULL) continue;
|
if (nfh == NULL) continue;
|
||||||
if (nf1 == NULL) nf1 = nfh;
|
if (nf1 == NULL) nf1 = nfh;
|
||||||
else if (ri_better(po, &nfh->n, NULL, &nf1->n, NULL, po->rfc1583)) nf1 = nfh;
|
else if (ri_better(po, &nfh->n, NULL, &nf1->n, NULL, po->rfc1583)) nf1 = nfh;
|
||||||
|
@ -915,7 +915,7 @@ ospf_ext_spf(struct proto_ospf *po)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nf2 = fib_route(&po->rtf, rt_fwaddr, 32);
|
nf2 = fib_route(&po->rtf, rt_fwaddr, MAX_PREFIX_LENGTH);
|
||||||
|
|
||||||
if (!nf2)
|
if (!nf2)
|
||||||
{
|
{
|
||||||
|
@ -923,7 +923,6 @@ ospf_ext_spf(struct proto_ospf *po)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((nn = neigh_find(p, &rt_fwaddr, 0)) != NULL)
|
if ((nn = neigh_find(p, &rt_fwaddr, 0)) != NULL)
|
||||||
{
|
{
|
||||||
nh = rt_fwaddr;
|
nh = rt_fwaddr;
|
||||||
|
@ -1179,7 +1178,7 @@ again1:
|
||||||
int found = 0;
|
int found = 0;
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
struct top_hash_entry *en;
|
struct top_hash_entry *en;
|
||||||
OSPF_TRACE(D_EVENTS, "Trying to find correct next hop");
|
OSPF_TRACE(D_EVENTS, "Trying to find correct next hop %I/%d via %I", nf->fn.prefix, nf->fn.pxlen, nf->n.nh);
|
||||||
WALK_LIST(ifa, po->iface_list)
|
WALK_LIST(ifa, po->iface_list)
|
||||||
{
|
{
|
||||||
if ((ifa->type == OSPF_IT_VLINK) && ipa_equal(ifa->vip, nf->n.nh))
|
if ((ifa->type == OSPF_IT_VLINK) && ipa_equal(ifa->vip, nf->n.nh))
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
void originate_prefix_rt_lsa(struct ospf_area *oa);
|
void originate_prefix_rt_lsa(struct ospf_area *oa);
|
||||||
void originate_prefix_net_lsa(struct ospf_iface *ifa);
|
void originate_prefix_net_lsa(struct ospf_iface *ifa);
|
||||||
|
void flush_prefix_net_lsa(struct ospf_iface *ifa);
|
||||||
|
|
||||||
#ifdef OSPFv2
|
#ifdef OSPFv2
|
||||||
#define ipa_to_rid(x) _I(x)
|
#define ipa_to_rid(x) _I(x)
|
||||||
|
@ -557,8 +558,6 @@ flush_net_lsa(struct ospf_iface *ifa)
|
||||||
ifa->net_lsa->lsa.age = LSA_MAXAGE;
|
ifa->net_lsa->lsa.age = LSA_MAXAGE;
|
||||||
lsasum_calculate(&ifa->net_lsa->lsa, ifa->net_lsa->lsa_body);
|
lsasum_calculate(&ifa->net_lsa->lsa, ifa->net_lsa->lsa_body);
|
||||||
ospf_lsupd_flood(po, NULL, NULL, &ifa->net_lsa->lsa, dom, 0);
|
ospf_lsupd_flood(po, NULL, NULL, &ifa->net_lsa->lsa, dom, 0);
|
||||||
|
|
||||||
|
|
||||||
flush_lsa(ifa->net_lsa, po);
|
flush_lsa(ifa->net_lsa, po);
|
||||||
ifa->net_lsa = NULL;
|
ifa->net_lsa = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1215,6 +1214,28 @@ originate_prefix_net_lsa(struct ospf_iface *ifa)
|
||||||
ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
|
ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
flush_prefix_net_lsa(struct ospf_iface *ifa)
|
||||||
|
{
|
||||||
|
struct proto_ospf *po = ifa->oa->po;
|
||||||
|
struct proto *p = &po->proto;
|
||||||
|
struct top_hash_entry *en = ifa->pxn_lsa;
|
||||||
|
u32 dom = ifa->oa->areaid;
|
||||||
|
|
||||||
|
if (en == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
OSPF_TRACE(D_EVENTS, "Flushing Net Prefix lsa for iface \"%s\".",
|
||||||
|
ifa->iface->name);
|
||||||
|
en->lsa.sn += 1;
|
||||||
|
en->lsa.age = LSA_MAXAGE;
|
||||||
|
lsasum_calculate(&en->lsa, en->lsa_body);
|
||||||
|
ospf_lsupd_flood(po, NULL, NULL, &en->lsa, dom, 0);
|
||||||
|
flush_lsa(en, po);
|
||||||
|
ifa->pxn_lsa = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -636,6 +636,12 @@ fill_in_sockaddr(sockaddr *sa, ip_addr a, unsigned port)
|
||||||
set_inaddr(&sa->sin6_addr, a);
|
set_inaddr(&sa->sin6_addr, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
fill_in_sockifa(sockaddr *sa, struct iface *ifa)
|
||||||
|
{
|
||||||
|
sa->sin6_scope_id = ifa ? ifa->index : 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
get_sockaddr(struct sockaddr_in6 *sa, ip_addr *a, unsigned *port, int check)
|
get_sockaddr(struct sockaddr_in6 *sa, ip_addr *a, unsigned *port, int check)
|
||||||
{
|
{
|
||||||
|
@ -661,6 +667,11 @@ fill_in_sockaddr(sockaddr *sa, ip_addr a, unsigned port)
|
||||||
set_inaddr(&sa->sin_addr, a);
|
set_inaddr(&sa->sin_addr, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
fill_in_sockifa(sockaddr *sa, struct iface *ifa)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
get_sockaddr(struct sockaddr_in *sa, ip_addr *a, unsigned *port, int check)
|
get_sockaddr(struct sockaddr_in *sa, ip_addr *a, unsigned *port, int check)
|
||||||
{
|
{
|
||||||
|
@ -874,10 +885,8 @@ sk_open(sock *s)
|
||||||
{
|
{
|
||||||
case SK_UDP:
|
case SK_UDP:
|
||||||
case SK_IP:
|
case SK_IP:
|
||||||
|
#ifndef IPV6
|
||||||
if (s->iface) /* It's a broadcast socket */
|
if (s->iface) /* It's a broadcast socket */
|
||||||
#ifdef IPV6
|
|
||||||
bug("IPv6 has no broadcasts");
|
|
||||||
#else
|
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) < 0)
|
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) < 0)
|
||||||
ERR("SO_BROADCAST");
|
ERR("SO_BROADCAST");
|
||||||
#endif
|
#endif
|
||||||
|
@ -911,7 +920,7 @@ sk_open(sock *s)
|
||||||
if (setsockopt(fd, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
if (setsockopt(fd, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||||
ERR("IPV6_ADD_MEMBERSHIP");
|
ERR("IPV6_ADD_MEMBERSHIP");
|
||||||
}
|
}
|
||||||
#else
|
#else /* IPv4 */
|
||||||
/* With IPv4 there are zillions of different socket interface variants. Ugh. */
|
/* With IPv4 there are zillions of different socket interface variants. Ugh. */
|
||||||
ASSERT(s->iface && s->iface->addr);
|
ASSERT(s->iface && s->iface->addr);
|
||||||
if (err = sysio_mcast_join(s))
|
if (err = sysio_mcast_join(s))
|
||||||
|
@ -933,6 +942,7 @@ sk_open(sock *s)
|
||||||
ERR("SO_REUSEADDR");
|
ERR("SO_REUSEADDR");
|
||||||
}
|
}
|
||||||
fill_in_sockaddr(&sa, s->saddr, port);
|
fill_in_sockaddr(&sa, s->saddr, port);
|
||||||
|
fill_in_sockifa(&sa, s->iface);
|
||||||
#ifdef CONFIG_SKIP_MC_BIND
|
#ifdef CONFIG_SKIP_MC_BIND
|
||||||
if ((type != SK_UDP_MC) && (type != SK_IP_MC) &&
|
if ((type != SK_UDP_MC) && (type != SK_IP_MC) &&
|
||||||
bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0)
|
bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0)
|
||||||
|
@ -1067,8 +1077,9 @@ sk_maybe_write(sock *s)
|
||||||
|
|
||||||
if (s->tbuf == s->tpos)
|
if (s->tbuf == s->tpos)
|
||||||
return 1;
|
return 1;
|
||||||
fill_in_sockaddr(&sa, s->faddr, s->fport);
|
|
||||||
|
|
||||||
|
fill_in_sockaddr(&sa, s->faddr, s->fport);
|
||||||
|
fill_in_sockifa(&sa, s->iface);
|
||||||
e = sendto(s->fd, s->tbuf, s->tpos - s->tbuf, 0, (struct sockaddr *) &sa, sizeof(sa));
|
e = sendto(s->fd, s->tbuf, s->tpos - s->tbuf, 0, (struct sockaddr *) &sa, sizeof(sa));
|
||||||
if (e < 0)
|
if (e < 0)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue