0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

Merge branch 'master' of ssh://git.nic.cz/bird

This commit is contained in:
Ondrej Filip 2012-05-15 23:40:37 +02:00
commit 3fe1d9e4a4
13 changed files with 103 additions and 47 deletions

View File

@ -1811,7 +1811,7 @@ protocol ospf <name> {
summary <switch>; summary <switch>;
cost <num>; cost <num>;
} }
interface <interface pattern> { interface <interface pattern> [instance <num>] {
cost <num>; cost <num>;
stub <switch>; stub <switch>;
hello <num>; hello <num>;
@ -1825,6 +1825,7 @@ protocol ospf <name> {
type [broadcast|bcast|pointopoint|ptp| type [broadcast|bcast|pointopoint|ptp|
nonbroadcast|nbma|pointomultipoint|ptmp]; nonbroadcast|nbma|pointomultipoint|ptmp];
strict nonbroadcast <switch>; strict nonbroadcast <switch>;
real broadcast <switch>;
check link <switch>; check link <switch>;
ecmp weight <num>; ecmp weight <num>;
authentication [none|simple|cryptographic]; authentication [none|simple|cryptographic];
@ -1841,7 +1842,7 @@ protocol ospf <name> {
<ip> eligible; <ip> eligible;
}; };
}; };
virtual link <id> { virtual link <id> [instance <num>] {
hello <num>; hello <num>;
retransmit <num>; retransmit <num>;
wait <num>; wait <num>;
@ -1961,14 +1962,19 @@ protocol ospf <name> {
subnetworks of given stub network are suppressed. This might subnetworks of given stub network are suppressed. This might
be used, for example, to aggregate generated stub networks. be used, for example, to aggregate generated stub networks.
<tag>interface <M>pattern</M></tag> <tag>interface <M>pattern</M> [instance <m/num/]</tag>
Defines that the specified interfaces belong to the area being defined. Defines that the specified interfaces belong to the area being defined.
See <ref id="dsc-iface" name="interface"> common option for detailed description. See <ref id="dsc-iface" name="interface"> common option for detailed description.
In OSPFv3, you can specify instance ID for that interface
description, so it is possible to have several instances of
that interface with different options or even in different areas.
<tag>virtual link <M>id</M></tag> <tag>virtual link <M>id</M> [instance <m/num/]</tag>
Virtual link to router with the router id. Virtual link acts as a Virtual link to router with the router id. Virtual link acts
point-to-point interface belonging to backbone. The actual area is as a point-to-point interface belonging to backbone. The
used as transport area. This item cannot be in the backbone. actual area is used as transport area. This item cannot be in
the backbone. In OSPFv3, you could also use several virtual
links to one destination with different instance IDs.
<tag>cost <M>num</M></tag> <tag>cost <M>num</M></tag>
Specifies output cost (metric) of an interface. Default value is 10. Specifies output cost (metric) of an interface. Default value is 10.
@ -2053,6 +2059,16 @@ protocol ospf &lt;name&gt; {
If set, don't send hello to any undefined neighbor. This switch If set, don't send hello to any undefined neighbor. This switch
is ignored on other than NBMA or PtMP networks. Default value is no. is ignored on other than NBMA or PtMP networks. Default value is no.
<tag>real broadcast <m/switch/</tag>
In <cf/type broadcast/ or <cf/type ptp/ network
configuration, OSPF packets are sent as IP multicast
packets. This option changes the behavior to using
old-fashioned IP broadcast packets. This may be useful as a
workaround if IP multicast for some reason does not work or
does not work reliably. This is a non-standard option and
probably is not interoperable with other OSPF
implementations. Default value is no.
<tag>check link <M>switch</M></tag> <tag>check link <M>switch</M></tag>
If set, a hardware link state (reported by OS) is taken into If set, a hardware link state (reported by OS) is taken into
consideration. When a link disappears (e.g. an ethernet cable is consideration. When a link disappears (e.g. an ethernet cable is

View File

@ -799,10 +799,7 @@ void
rte_dump(rte *e) rte_dump(rte *e)
{ {
net *n = e->net; net *n = e->net;
if (n)
debug("%-1I/%2d ", n->n.prefix, n->n.pxlen); debug("%-1I/%2d ", n->n.prefix, n->n.pxlen);
else
debug("??? ");
debug("KF=%02x PF=%02x pref=%d lm=%d ", n->n.flags, e->pflags, e->pref, now-e->lastmod); debug("KF=%02x PF=%02x pref=%d lm=%d ", n->n.flags, e->pflags, e->pref, now-e->lastmod);
rta_dump(e->attrs); rta_dump(e->attrs);
if (e->attrs->proto->proto->dump_attrs) if (e->attrs->proto->proto->dump_attrs)

View File

@ -1031,9 +1031,6 @@ bgp_do_rx_update(struct bgp_conn *conn,
if (n = net_find(p->p.table, prefix, pxlen)) if (n = net_find(p->p.table, prefix, pxlen))
rte_update(p->p.table, n, &p->p, &p->p, NULL); rte_update(p->p.table, n, &p->p, &p->p, NULL);
} }
if (bgp_apply_limits(p) < 0)
goto done;
} }
} }

View File

@ -107,7 +107,17 @@ static inline void
check_defcost(int cost) check_defcost(int cost)
{ {
if ((cost <= 0) || (cost >= LSINFINITY)) if ((cost <= 0) || (cost >= LSINFINITY))
cf_error("Default cost must be in range 1-%d", LSINFINITY); cf_error("Default cost must be in range 1-%d", LSINFINITY-1);
}
static inline void
set_instance_id(unsigned id)
{
#ifdef OSPFv3
OSPF_PATT->instance_id = id;
#else
cf_error("Instance ID requires OSPFv3");
#endif
} }
CF_DECLS CF_DECLS
@ -120,7 +130,7 @@ CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK) CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK)
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, TAG, EXTERNAL) CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, TAG, EXTERNAL)
CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY) CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY)
CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF) CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE, REAL)
%type <t> opttext %type <t> opttext
%type <ld> lsadb_args %type <ld> lsadb_args
@ -218,8 +228,8 @@ ospf_stubnet_item:
; ;
ospf_vlink: ospf_vlink:
ospf_vlink_start '{' ospf_vlink_opts '}' { ospf_iface_finish(); } ospf_vlink_start ospf_instance_id '{' ospf_vlink_opts '}' { ospf_iface_finish(); }
| ospf_vlink_start { ospf_iface_finish(); } | ospf_vlink_start ospf_instance_id { ospf_iface_finish(); }
; ;
ospf_vlink_opts: ospf_vlink_opts:
@ -277,6 +287,7 @@ ospf_iface_item:
| TYPE PTP { OSPF_PATT->type = OSPF_IT_PTP ; } | TYPE PTP { OSPF_PATT->type = OSPF_IT_PTP ; }
| TYPE POINTOMULTIPOINT { OSPF_PATT->type = OSPF_IT_PTMP ; } | TYPE POINTOMULTIPOINT { OSPF_PATT->type = OSPF_IT_PTMP ; }
| TYPE PTMP { OSPF_PATT->type = OSPF_IT_PTMP ; } | TYPE PTMP { OSPF_PATT->type = OSPF_IT_PTMP ; }
| REAL BROADCAST bool { OSPF_PATT->real_bcast = $3; if (OSPF_VERSION != 2) cf_error("Real broadcast option requires OSPFv2"); }
| TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); } | TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); }
| PRIORITY expr { OSPF_PATT->priority = $2 ; if (($2<0) || ($2>255)) cf_error("Priority must be in range 0-255"); } | PRIORITY expr { OSPF_PATT->priority = $2 ; if (($2<0) || ($2>255)) cf_error("Priority must be in range 0-255"); }
| STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; } | STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; }
@ -364,6 +375,11 @@ ospf_iface_start:
} }
; ;
ospf_instance_id:
/* empty */
| INSTANCE expr { set_instance_id($2); }
;
ospf_iface_opts: ospf_iface_opts:
/* empty */ /* empty */
| ospf_iface_opts ospf_iface_item ';' | ospf_iface_opts ospf_iface_item ';'
@ -375,7 +391,7 @@ ospf_iface_opt_list:
; ;
ospf_iface: ospf_iface:
ospf_iface_start iface_patt_list ospf_iface_opt_list { ospf_iface_finish(); } ospf_iface_start iface_patt_list ospf_instance_id ospf_iface_opt_list { ospf_iface_finish(); }
; ;
opttext: opttext:

View File

@ -303,7 +303,7 @@ ospf_hello_send(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn)
{ {
case OSPF_IT_BCAST: case OSPF_IT_BCAST:
case OSPF_IT_PTP: case OSPF_IT_PTP:
ospf_send_to(ifa, AllSPFRouters); ospf_send_to_all(ifa);
break; break;
case OSPF_IT_NBMA: case OSPF_IT_NBMA:

View File

@ -120,14 +120,25 @@ ospf_sk_open(struct ospf_iface *ifa)
sk->saddr = ifa->addr->ip; sk->saddr = ifa->addr->ip;
if ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_PTP)) if ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_PTP))
{ {
if (ifa->cf->real_bcast)
{
ifa->all_routers = ifa->addr->brd;
if (sk_set_broadcast(sk, 1) < 0)
goto err;
}
else
{
ifa->all_routers = AllSPFRouters;
sk->ttl = 1; /* Hack, this will affect just multicast packets */ sk->ttl = 1; /* Hack, this will affect just multicast packets */
if (sk_setup_multicast(sk) < 0) if (sk_setup_multicast(sk) < 0)
goto err; goto err;
if (sk_join_group(sk, AllSPFRouters) < 0) if (sk_join_group(sk, ifa->all_routers) < 0)
goto err; goto err;
} }
}
ifa->sk = sk; ifa->sk = sk;
ifa->sk_dr = 0; ifa->sk_dr = 0;
@ -265,7 +276,7 @@ ospf_iface_chstate(struct ospf_iface *ifa, u8 state)
OSPF_TRACE(D_EVENTS, "Changing state of iface %s from %s to %s", OSPF_TRACE(D_EVENTS, "Changing state of iface %s from %s to %s",
ifa->iface->name, ospf_is[oldstate], ospf_is[state]); ifa->iface->name, ospf_is[oldstate], ospf_is[state]);
if ((ifa->type == OSPF_IT_BCAST) && ifa->sk) if ((ifa->type == OSPF_IT_BCAST) && !ifa->cf->real_bcast && ifa->sk)
{ {
if ((state == OSPF_IS_BACKUP) || (state == OSPF_IS_DR)) if ((state == OSPF_IS_BACKUP) || (state == OSPF_IS_DR))
ospf_sk_join_dr(ifa); ospf_sk_join_dr(ifa);
@ -536,6 +547,7 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
/* Check validity of interface type */ /* Check validity of interface type */
int old_type = ifa->type; int old_type = ifa->type;
u32 if_multi_flag = ip->real_bcast ? IF_BROADCAST : IF_MULTICAST;
#ifdef OSPFv2 #ifdef OSPFv2
if ((ifa->type == OSPF_IT_BCAST) && (addr->flags & IA_PEER)) if ((ifa->type == OSPF_IT_BCAST) && (addr->flags & IA_PEER))
@ -545,10 +557,10 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
ifa->type = OSPF_IT_PTMP; ifa->type = OSPF_IT_PTMP;
#endif #endif
if ((ifa->type == OSPF_IT_BCAST) && !(iface->flags & IF_MULTICAST)) if ((ifa->type == OSPF_IT_BCAST) && !(iface->flags & if_multi_flag))
ifa->type = OSPF_IT_NBMA; ifa->type = OSPF_IT_NBMA;
if ((ifa->type == OSPF_IT_PTP) && !(iface->flags & IF_MULTICAST)) if ((ifa->type == OSPF_IT_PTP) && !(iface->flags & if_multi_flag))
ifa->type = OSPF_IT_PTMP; ifa->type = OSPF_IT_PTMP;
if (ifa->type != old_type) if (ifa->type != old_type)
@ -628,6 +640,9 @@ ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new)
if (ifa->stub != new_stub) if (ifa->stub != new_stub)
return 0; return 0;
if (new->real_bcast != ifa->cf->real_bcast)
return 0;
ifa->cf = new; ifa->cf = new;
ifa->marked = 0; ifa->marked = 0;
@ -1099,11 +1114,15 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
void void
ospf_iface_info(struct ospf_iface *ifa) ospf_iface_info(struct ospf_iface *ifa)
{ {
char *strict = ""; char *more = "";
if (ifa->strictnbma && if (ifa->strictnbma &&
((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP))) ((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP)))
strict = "(strict)"; more = " (strict)";
if (ifa->cf->real_bcast &&
((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_PTP)))
more = " (real)";
if (ifa->type == OSPF_IT_VLINK) if (ifa->type == OSPF_IT_VLINK)
{ {
@ -1124,11 +1143,10 @@ ospf_iface_info(struct ospf_iface *ifa)
#else /* OSPFv3 */ #else /* OSPFv3 */
cli_msg(-1015, "Interface %s (IID %d)", ifa->iface->name, ifa->instance_id); cli_msg(-1015, "Interface %s (IID %d)", ifa->iface->name, ifa->instance_id);
#endif #endif
cli_msg(-1015, "\tType: %s %s", ospf_it[ifa->type], strict); cli_msg(-1015, "\tType: %s%s", ospf_it[ifa->type], more);
cli_msg(-1015, "\tArea: %R (%u)", ifa->oa->areaid, ifa->oa->areaid); cli_msg(-1015, "\tArea: %R (%u)", ifa->oa->areaid, ifa->oa->areaid);
} }
cli_msg(-1015, "\tState: %s %s", ospf_is[ifa->state], cli_msg(-1015, "\tState: %s%s", ospf_is[ifa->state], ifa->stub ? " (stub)" : "");
ifa->stub ? "(stub)" : "");
cli_msg(-1015, "\tPriority: %u", ifa->priority); cli_msg(-1015, "\tPriority: %u", ifa->priority);
cli_msg(-1015, "\tCost: %u", ifa->cost); cli_msg(-1015, "\tCost: %u", ifa->cost);
if (ifa->oa->po->ecmp) if (ifa->oa->po->ecmp)

View File

@ -97,7 +97,9 @@ ospf_lsack_send(struct ospf_neighbor *n, int queue)
if (ifa->type == OSPF_IT_BCAST) if (ifa->type == OSPF_IT_BCAST)
{ {
if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP)) if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP))
ospf_send_to(ifa, AllSPFRouters); ospf_send_to_all(ifa);
else if (ifa->cf->real_bcast)
ospf_send_to_bdr(ifa);
else else
ospf_send_to(ifa, AllDRouters); ospf_send_to(ifa, AllDRouters);
} }
@ -124,7 +126,9 @@ ospf_lsack_send(struct ospf_neighbor *n, int queue)
if (ifa->type == OSPF_IT_BCAST) if (ifa->type == OSPF_IT_BCAST)
{ {
if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP)) if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP))
ospf_send_to(ifa, AllSPFRouters); ospf_send_to_all(ifa);
else if (ifa->cf->real_bcast)
ospf_send_to_bdr(ifa);
else else
ospf_send_to(ifa, AllDRouters); ospf_send_to(ifa, AllDRouters);
} }

View File

@ -314,7 +314,9 @@ ospf_lsupd_flood(struct proto_ospf *po,
{ {
case OSPF_IT_BCAST: case OSPF_IT_BCAST:
if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR)) if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR))
ospf_send_to(ifa, AllSPFRouters); ospf_send_to_all(ifa);
else if (ifa->cf->real_bcast)
ospf_send_to_bdr(ifa);
else else
ospf_send_to(ifa, AllDRouters); ospf_send_to(ifa, AllDRouters);
break; break;
@ -327,7 +329,7 @@ ospf_lsupd_flood(struct proto_ospf *po,
break; break;
case OSPF_IT_PTP: case OSPF_IT_PTP:
ospf_send_to(ifa, AllSPFRouters); ospf_send_to_all(ifa);
break; break;
case OSPF_IT_PTMP: case OSPF_IT_PTMP:

View File

@ -205,6 +205,7 @@ struct ospf_iface
bird_clock_t csn_use; /* Last time when packet with that CSN was sent */ bird_clock_t csn_use; /* Last time when packet with that CSN was sent */
#endif #endif
ip_addr all_routers; /* */
ip_addr drip; /* Designated router */ ip_addr drip; /* Designated router */
ip_addr bdrip; /* Backup DR */ ip_addr bdrip; /* Backup DR */
u32 drid; u32 drid;
@ -790,22 +791,23 @@ struct ospf_iface_patt
u32 deadc; u32 deadc;
u32 deadint; u32 deadint;
u32 inftransdelay; u32 inftransdelay;
u32 priority;
u32 strictnbma;
list nbma_list; list nbma_list;
u32 priority;
u32 voa; u32 voa;
u32 vid; u32 vid;
u16 rxbuf; u16 rxbuf;
u8 check_link;
u8 ecmp_weight;
#define OSPF_RXBUF_NORMAL 0 #define OSPF_RXBUF_NORMAL 0
#define OSPF_RXBUF_LARGE 1 #define OSPF_RXBUF_LARGE 1
#define OSPF_RXBUF_MINSIZE 256 /* Minimal allowed size */ #define OSPF_RXBUF_MINSIZE 256 /* Minimal allowed size */
u32 autype; /* Not really used in OSPFv3 */ u16 autype; /* Not really used in OSPFv3 */
#define OSPF_AUTH_NONE 0 #define OSPF_AUTH_NONE 0
#define OSPF_AUTH_SIMPLE 1 #define OSPF_AUTH_SIMPLE 1
#define OSPF_AUTH_CRYPT 2 #define OSPF_AUTH_CRYPT 2
#define OSPF_AUTH_CRYPT_SIZE 16 #define OSPF_AUTH_CRYPT_SIZE 16
u8 strictnbma;
u8 check_link;
u8 ecmp_weight;
u8 real_bcast; /* Not really used in OSPFv3 */
#ifdef OSPFv2 #ifdef OSPFv2
list *passwords; list *passwords;

View File

@ -273,7 +273,7 @@ ospf_rx_hook(sock *sk, int size)
int src_local, dst_local UNUSED, dst_mcast; int src_local, dst_local UNUSED, dst_mcast;
src_local = ipa_in_net(sk->faddr, ifa->addr->prefix, ifa->addr->pxlen); src_local = ipa_in_net(sk->faddr, ifa->addr->prefix, ifa->addr->pxlen);
dst_local = ipa_equal(sk->laddr, ifa->addr->ip); dst_local = ipa_equal(sk->laddr, ifa->addr->ip);
dst_mcast = ipa_equal(sk->laddr, AllSPFRouters) || ipa_equal(sk->laddr, AllDRouters); dst_mcast = ipa_equal(sk->laddr, ifa->all_routers) || ipa_equal(sk->laddr, AllDRouters);
#ifdef OSPFv2 #ifdef OSPFv2
/* First, we eliminate packets with strange address combinations. /* First, we eliminate packets with strange address combinations.
@ -287,6 +287,9 @@ ospf_rx_hook(sock *sk, int size)
if (!dst_mcast && !dst_local) if (!dst_mcast && !dst_local)
return 1; return 1;
/* Ignore my own broadcast packets */
if (ifa->cf->real_bcast && ipa_equal(sk->faddr, ifa->addr->ip))
return 1;
#else /* OSPFv3 */ #else /* OSPFv3 */
/* In OSPFv3, src_local and dst_local mean link-local. /* In OSPFv3, src_local and dst_local mean link-local.

View File

@ -19,6 +19,8 @@ void ospf_send_to_agt(struct ospf_iface *ifa, u8 state);
void ospf_send_to_bdr(struct ospf_iface *ifa); void ospf_send_to_bdr(struct ospf_iface *ifa);
void ospf_send_to(struct ospf_iface *ifa, ip_addr ip); void ospf_send_to(struct ospf_iface *ifa, ip_addr ip);
static inline void ospf_send_to_all(struct ospf_iface *ifa) { ospf_send_to(ifa, ifa->all_routers); }
static inline void * ospf_tx_buffer(struct ospf_iface *ifa) { return ifa->sk->tbuf; } static inline void * ospf_tx_buffer(struct ospf_iface *ifa) { return ifa->sk->tbuf; }
static inline unsigned static inline unsigned

View File

@ -624,7 +624,6 @@ rip_dump(struct proto *p)
int i; int i;
node *w; node *w;
struct rip_interface *rif; struct rip_interface *rif;
i = 0;
CHK_MAGIC; CHK_MAGIC;
WALK_LIST( w, P->connections ) { WALK_LIST( w, P->connections ) {
@ -995,8 +994,8 @@ static int
rip_get_attr(eattr *a, byte *buf, int buflen UNUSED) rip_get_attr(eattr *a, byte *buf, int buflen UNUSED)
{ {
switch (a->id) { switch (a->id) {
case EA_RIP_METRIC: buf += bsprintf( buf, "metric: %d", a->u.data ); return GA_FULL; case EA_RIP_METRIC: bsprintf( buf, "metric: %d", a->u.data ); return GA_FULL;
case EA_RIP_TAG: buf += bsprintf( buf, "tag: %d", a->u.data ); return GA_FULL; case EA_RIP_TAG: bsprintf( buf, "tag: %d", a->u.data ); return GA_FULL;
default: return GA_UNKNOWN; default: return GA_UNKNOWN;
} }
} }

View File

@ -301,7 +301,7 @@ sk_set_min_ttl6(sock *s, int ttl)
if (errno == ENOPROTOOPT) if (errno == ENOPROTOOPT)
log(L_ERR "Kernel does not support IPv6 TTL security"); log(L_ERR "Kernel does not support IPv6 TTL security");
else else
log(L_ERR "sk_set_min_ttl4: setsockopt: %m"); log(L_ERR "sk_set_min_ttl6: setsockopt: %m");
return -1; return -1;
} }