summaryrefslogtreecommitdiffstats
path: root/proto/bgp
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2010-11-03 01:40:36 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2010-11-03 01:40:36 +0100
commita244c5524b30874e24fc4dfbdb8cef243bd33178 (patch)
tree2856262ff6d1cbb9470dde9e7f4cabd3030ef973 /proto/bgp
parent938b191b9282b138cbdd30dfc11b78c0467d6380 (diff)
downloadbird-a244c5524b30874e24fc4dfbdb8cef243bd33178.tar
bird-a244c5524b30874e24fc4dfbdb8cef243bd33178.zip
Added support for sending and handling the multicast capability
Diffstat (limited to 'proto/bgp')
-rw-r--r--proto/bgp/bgp.c7
-rw-r--r--proto/bgp/bgp.h14
-rw-r--r--proto/bgp/config.Y4
-rw-r--r--proto/bgp/packets.c42
4 files changed, 54 insertions, 13 deletions
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index ba5d755..cbffc65 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -408,6 +408,8 @@ bgp_send_open(struct bgp_conn *conn)
conn->start_state = conn->bgp->start_state;
conn->want_as4_support = conn->bgp->cf->enable_as4 && (conn->start_state != BSS_CONNECT_NOCAP);
conn->peer_as4_support = 0; // Default value, possibly changed by receiving capability.
+ conn->want_multicast_support = conn->bgp->cf->c.global->enable_multicast && conn->bgp->cf->enable_multicast && (conn->start_state != BSS_CONNECT_NOCAP);
+ conn->peer_multicast_support = 0; // Default value, possibly changed by receiving capability.
conn->advertised_as = 0;
DBG("BGP: Sending open\n");
@@ -1067,9 +1069,10 @@ bgp_show_proto_info(struct proto *P)
cli_msg(-1006, " Neighbor ID: %R", p->remote_id);
cli_msg(-1006, " Neighbor address: %I", p->cf->remote_ip);
cli_msg(-1006, " Source address: %I", p->source_addr);
- cli_msg(-1006, " Neighbor caps: %s%s",
+ cli_msg(-1006, " Neighbor caps: %s%s%s",
c->peer_refresh_support ? " refresh" : "",
- c->peer_as4_support ? " AS4" : "");
+ c->peer_as4_support ? " AS4" : "",
+ c->peer_multicast_support ? " multicast" : "");
if (p->cf->route_limit)
cli_msg(-1006, " Route limit: %d/%d",
p->p.stats.imp_routes, p->cf->route_limit);
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index b06f20a..359bd9c 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -32,6 +32,7 @@ struct bgp_config {
int capabilities; /* Enable capability handshake [RFC3392] */
int enable_refresh; /* Enable local support for route refresh [RFC2918] */
int enable_as4; /* Enable local support for 4B AS numbers [RFC4893] */
+ int enable_multicast; /* Enable local support for multicast routes [RFC4760] */
u32 rr_cluster_id; /* Route reflector cluster ID, if different from local ID */
int rr_client; /* Whether neighbor is RR client of me */
int rs_client; /* Whether neighbor is RS client of me */
@@ -73,6 +74,8 @@ struct bgp_conn {
int start_state; /* protocol start_state snapshot when connection established */
int want_as4_support; /* Connection tries to establish AS4 session */
int peer_as4_support; /* Peer supports 4B AS numbers [RFC4893] */
+ int want_multicast_support; /* We want to exchange multicast routes */
+ int peer_multicast_support; /* Peer supports multicast routes [RFC4760] */
int peer_refresh_support; /* Peer supports route refresh [RFC2918] */
unsigned hold_time, keepalive_time; /* Times calculated from my and neighbor's requirements */
};
@@ -108,11 +111,9 @@ struct bgp_proto {
u8 last_error_class; /* Error class of last error */
u32 last_error_code; /* Error code of last error. BGP protocol errors
are encoded as (bgp_err_code << 16 | bgp_err_subcode) */
-#ifdef IPV6
byte *mp_reach_start, *mp_unreach_start; /* Multiprotocol BGP attribute notes */
unsigned mp_reach_len, mp_unreach_len;
ip_addr local_link; /* Link-level version of source_addr */
-#endif
};
struct bgp_prefix {
@@ -297,6 +298,12 @@ void bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsi
#define ORIGIN_EGP 1
#define ORIGIN_INCOMPLETE 2
+/* Capabilities */
+
+#define BGP_CAP_MP 1
+#define BGP_CAP_REFRESH 2
+#define BGP_CAP_AS4 65
+
/* Address families */
#define BGP_AF_IPV4 1
@@ -308,4 +315,7 @@ void bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsi
#define BGP_AF BGP_AF_IPV4
#endif
+#define BGP_SAF_UNICAST 1
+#define BGP_SAF_MULTICAST 2
+
#endif
diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y
index e932a7f..2e76159 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -25,7 +25,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
ADVERTISE, IPV4, CAPABILITIES, LIMIT, PASSIVE, PREFER, OLDER,
MISSING, LLADDR, DROP, IGNORE, ROUTE, REFRESH, INTERPRET,
COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP, TABLE,
- GATEWAY, DIRECT, RECURSIVE)
+ GATEWAY, DIRECT, RECURSIVE, MULTICAST)
CF_GRAMMAR
@@ -45,6 +45,7 @@ bgp_proto_start: proto_start BGP {
BGP_CFG->error_delay_time_max = 300;
BGP_CFG->enable_refresh = 1;
BGP_CFG->enable_as4 = 1;
+ BGP_CFG->enable_multicast = 1;
BGP_CFG->capabilities = 2;
BGP_CFG->advertise_ipv4 = 1;
BGP_CFG->interpret_communities = 1;
@@ -90,6 +91,7 @@ bgp_proto:
| bgp_proto DISABLE AFTER ERROR bool ';' { BGP_CFG->disable_after_error = $5; }
| bgp_proto ENABLE ROUTE REFRESH bool ';' { BGP_CFG->enable_refresh = $5; }
| bgp_proto ENABLE AS4 bool ';' { BGP_CFG->enable_as4 = $4; }
+ | bgp_proto ENABLE MULTICAST bool ';' { BGP_CFG->enable_multicast = $4; }
| bgp_proto CAPABILITIES bool ';' { BGP_CFG->capabilities = $3; }
| bgp_proto ADVERTISE IPV4 bool ';' { BGP_CFG->advertise_ipv4 = $4; }
| bgp_proto PASSWORD TEXT ';' { BGP_CFG->password = $3; }
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index bf98640..1a1e7b7 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -117,12 +117,12 @@ bgp_create_notification(struct bgp_conn *conn, byte *buf)
static byte *
bgp_put_cap_ipv6(struct bgp_conn *conn UNUSED, byte *buf)
{
- *buf++ = 1; /* Capability 1: Multiprotocol extensions */
+ *buf++ = BGP_CAP_MP; /* Capability 1: Multiprotocol extensions */
*buf++ = 4; /* Capability data length */
*buf++ = 0; /* We support AF IPv6 */
*buf++ = BGP_AF_IPV6;
*buf++ = 0; /* RFU */
- *buf++ = 1; /* and SAFI 1 */
+ *buf++ = BGP_SAF_UNICAST; /* and SAFI 1 */
return buf;
}
@@ -131,20 +131,32 @@ bgp_put_cap_ipv6(struct bgp_conn *conn UNUSED, byte *buf)
static byte *
bgp_put_cap_ipv4(struct bgp_conn *conn UNUSED, byte *buf)
{
- *buf++ = 1; /* Capability 1: Multiprotocol extensions */
+ *buf++ = BGP_CAP_MP; /* Capability 1: Multiprotocol extensions */
*buf++ = 4; /* Capability data length */
*buf++ = 0; /* We support AF IPv4 */
*buf++ = BGP_AF_IPV4;
*buf++ = 0; /* RFU */
- *buf++ = 1; /* and SAFI 1 */
+ *buf++ = BGP_SAF_UNICAST; /* and SAFI 1 */
return buf;
}
#endif
static byte *
+bgp_put_cap_multicast(struct bgp_conn *conn UNUSED, byte *buf)
+{
+ *buf++ = BGP_CAP_MP; /* Capability 1: Multiprotocol extensions */
+ *buf++ = 4; /* Capability data length */
+ *buf++ = 0;
+ *buf++ = BGP_AF;
+ *buf++ = 0; /* RFU */
+ *buf++ = BGP_SAF_MULTICAST; /* and SAFI 2 */
+ return buf;
+}
+
+static byte *
bgp_put_cap_rr(struct bgp_conn *conn UNUSED, byte *buf)
{
- *buf++ = 2; /* Capability 2: Support for route refresh */
+ *buf++ = BGP_CAP_REFRESH; /* Capability 2: Support for route refresh */
*buf++ = 0; /* Capability data length */
return buf;
}
@@ -152,7 +164,7 @@ bgp_put_cap_rr(struct bgp_conn *conn UNUSED, byte *buf)
static byte *
bgp_put_cap_as4(struct bgp_conn *conn, byte *buf)
{
- *buf++ = 65; /* Capability 65: Support for 4-octet AS number */
+ *buf++ = BGP_CAP_AS4; /* Capability 65: Support for 4-octet AS number */
*buf++ = 4; /* Capability data length */
put_u32(buf, conn->bgp->local_as);
return buf + 4;
@@ -197,6 +209,9 @@ bgp_create_open(struct bgp_conn *conn, byte *buf)
if (conn->want_as4_support)
cap = bgp_put_cap_as4(conn, cap);
+ if (conn->want_multicast_support)
+ cap = bgp_put_cap_multicast(conn, cap);
+
cap_len = cap - buf - 12;
if (cap_len > 0)
{
@@ -625,13 +640,24 @@ bgp_parse_capabilities(struct bgp_conn *conn, byte *opt, int len)
switch (opt[0])
{
- case 2: /* Route refresh capability, RFC 2918 */
+ case BGP_CAP_MP: /* Multiprotocol capability, RFC 4760 */
+ if (cl != 4)
+ goto err;
+
+ if (get_u16(opt + 2) != BGP_AF)
+ break;
+
+ if (opt[5] == BGP_SAF_MULTICAST)
+ conn->peer_multicast_support = 1;
+ break;
+
+ case BGP_CAP_REFRESH: /* Route refresh capability, RFC 2918 */
if (cl != 0)
goto err;
conn->peer_refresh_support = 1;
break;
- case 65: /* AS4 capability, RFC 4893 */
+ case BGP_CAP_AS4: /* AS4 capability, RFC 4893 */
if (cl != 4)
goto err;
conn->peer_as4_support = 1;