Commit c217fe59 authored by Jan Maria Matejka's avatar Jan Maria Matejka
Browse files

Merge branch 'maarten' into mq-ordered

parents e3e42530 1a3aba56
Loading
Loading
Loading
Loading
+16 −9
Original line number Diff line number Diff line
@@ -1094,8 +1094,10 @@ bgp_decode_attrs(struct bgp_parse_state *s, byte *data, uint len)
    ADVANCE(pos, len, alen);
  }

#define FAIL(KEY) ({ STATS(KEY); goto fail; })

  if (s->err_withdraw)
    goto withdraw;
    FAIL(bad_attribute);

  /* If there is no reachability NLRI, we are finished */
  if (!s->ip_reach_len && !s->mp_reach_len)
@@ -1104,10 +1106,10 @@ bgp_decode_attrs(struct bgp_parse_state *s, byte *data, uint len)

  /* Handle missing mandatory attributes; RFC 7606 3 (d) */
  if (!BIT32_TEST(s->attrs_seen, BA_ORIGIN))
  { REPORT(NO_MANDATORY, "ORIGIN"); goto withdraw; }
  { REPORT(NO_MANDATORY, "ORIGIN"); FAIL(no_mandatory); }

  if (!BIT32_TEST(s->attrs_seen, BA_AS_PATH))
  { REPORT(NO_MANDATORY, "AS_PATH"); goto withdraw; }
  { REPORT(NO_MANDATORY, "AS_PATH"); FAIL(no_mandatory); }

  /* When receiving attributes from non-AS4-aware BGP speaker, we have to
     reconstruct AS_PATH and AGGREGATOR attributes; RFC 6793 4.2.3 */
@@ -1116,19 +1118,19 @@ bgp_decode_attrs(struct bgp_parse_state *s, byte *data, uint len)

  /* Reject routes with our ASN in AS_PATH attribute */
  if (bgp_as_path_loopy(p, attrs, p->local_as))
    goto withdraw;
    FAIL(loopy);

  /* Reject routes with our Confederation ID in AS_PATH attribute; RFC 5065 4.0 */
  if ((p->public_as != p->local_as) && bgp_as_path_loopy(p, attrs, p->public_as))
    goto withdraw;
    FAIL(loopy);

  /* Reject routes with our Router ID in ORIGINATOR_ID attribute; RFC 4456 8 */
  if (p->is_internal && bgp_originator_id_loopy(p, attrs))
    goto withdraw;
    FAIL(loopy);

  /* Reject routes with our Cluster ID in CLUSTER_LIST attribute; RFC 4456 8 */
  if (p->rr_client && bgp_cluster_list_loopy(p, attrs))
    goto withdraw;
    FAIL(loopy);

  /* If there is no local preference, define one */
  if (!BIT32_TEST(s->attrs_seen, BA_LOCAL_PREF))
@@ -1141,8 +1143,11 @@ framing_error:
  /* RFC 7606 4 - handle attribute framing errors */
  REPORT("Malformed attribute list - framing error (%u/%u) at %d",
	 alen, len, (int) (pos - s->attrs));
  FAIL(bad_alist);

#undef FAIL

withdraw:
fail:
  /* RFC 7606 5.2 - handle missing NLRI during errors */
  if (!s->ip_reach_len && !s->mp_reach_len)
    bgp_parse_error(s, 1);
@@ -2009,11 +2014,13 @@ bgp_get_attr(eattr *a, byte *buf, int buflen)
void
bgp_get_route_info(rte *e, byte *buf, ea_list *attrs)
{
  struct bgp_proto *bgp = (void *) e->attrs->src->proto;
  eattr *p = ea_find(attrs, EA_CODE(EAP_BGP, BA_AS_PATH));
  eattr *o = ea_find(attrs, EA_CODE(EAP_BGP, BA_ORIGIN));
  u32 origas;

  buf += bsprintf(buf, " (%d", e->pref);
  char c = bgp->is_internal ? 'I' : (bgp->is_interior ? 'C' : 'E');
  buf += bsprintf(buf, " %c (%d", c, e->pref);

  if (e->u.bgp.suppressed)
    buf += bsprintf(buf, "-");
+14 −0
Original line number Diff line number Diff line
@@ -1328,6 +1328,8 @@ bgp_start(struct proto *P)
  p->source_addr = p->cf->local_ip;
  p->link_addr = IPA_NONE;

  memset(&(p->stats), 0, sizeof(struct bgp_stats));

  /* Lock all channels when in GR recovery mode */
  if (p->p.gr_recovery && p->cf->gr_mode)
  {
@@ -2104,6 +2106,15 @@ bgp_show_proto_info(struct proto *P)
	    tm_remains(p->conn->keepalive_timer), p->conn->keepalive_time);
  }

  struct bgp_stats *s = &p->stats;
  cli_msg(-1006, "    Statistics:");
  cli_msg(-1006, "      rx-open %u  rx-update %u  rx-notify %u  rx-keepalive %u  rx-refresh %u",
	  s->rx_pkts[0], s->rx_pkts[1], s->rx_pkts[2], s->rx_pkts[3], s->rx_pkts[4]);
  cli_msg(-1006, "      tx-open %u  tx-update %u  tx-notify %u  tx-keepalive %u  tx-refresh %u",
	  s->tx_pkts[0], s->tx_pkts[1], s->tx_pkts[2], s->tx_pkts[3], s->tx_pkts[4]);
  cli_msg(-1006, "      bad-alist %u  bad-attribute %u  bad-next-hop %u  no-mandatory %u  loopy %u",
	  s->bad_alist, s->bad_attribute, s->bad_next_hop, s->no_mandatory, s->loopy);

  if ((p->last_error_class != BE_NONE) &&
      (p->last_error_class != BE_MAN_DOWN))
  {
@@ -2120,6 +2131,9 @@ bgp_show_proto_info(struct proto *P)

      if (c->c.channel_state == CS_UP)
      {
	cli_msg(-1006, "    Enqueued updates:   %u", c->bucket_hash.count);
	cli_msg(-1006, "    Enqueued prefixes:  %u", c->prefix_hash.count);

	if (ipa_zero(c->link_addr))
	  cli_msg(-1006, "    BGP Next hop:   %I", c->next_hop_addr);
	else
+11 −0
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ struct eattr;
#define BGP_AF_FLOW4		BGP_AF( BGP_AFI_IPV4, BGP_SAFI_FLOW )
#define BGP_AF_FLOW6		BGP_AF( BGP_AFI_IPV6, BGP_SAFI_FLOW )

#define BGP_PKT_TYPES		5	/* PKT_OPEN .. PKT_ROUTE_REFRESH */


struct bgp_write_state;
struct bgp_parse_state;
@@ -196,6 +198,14 @@ struct bgp_caps {
#define WALK_AF_CAPS(caps,ac) \
  for (ac = caps->af_data; ac < &caps->af_data[caps->af_count]; ac++)

struct bgp_stats {
  uint rx_pkts[BGP_PKT_TYPES], tx_pkts[BGP_PKT_TYPES];
  uint bad_alist, bad_attribute, bad_next_hop, no_mandatory, loopy;
};

#ifndef PARSER
#define STATS(KEY) ({ p->stats.KEY++; })
#endif

struct bgp_socket {
  node n;				/* Node in global bgp_sockets */
@@ -254,6 +264,7 @@ struct bgp_proto {
  struct neighbor *neigh;		/* Neighbor entry corresponding to remote ip, NULL if multihop */
  struct bgp_socket *sock;		/* Shared listening socket */
  struct bfd_request *bfd_req;		/* BFD request, if BFD is used */
  struct bgp_stats stats;		/* Packet statistics */
  ip_addr source_addr;			/* Local address used as an advertised next hop */
  ip_addr link_addr;			/* Link-local version of source_addr */
  event *event;				/* Event for respawning and shutting process */
+16 −2
Original line number Diff line number Diff line
@@ -2174,6 +2174,7 @@ bgp_rx_end_mark(struct bgp_parse_state *s, u32 afi)
static inline void
bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_list *ea, byte *nh, uint nh_len)
{
  struct bgp_proto *p = s->proto;
  struct bgp_channel *c = bgp_get_channel(s->proto, afi);
  rta *a = NULL;

@@ -2207,8 +2208,11 @@ bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_lis

    /* Handle withdraw during next hop decoding */
    if (s->err_withdraw)
    {
      STATS(bad_next_hop);
      a = NULL;
    }
  }

  c->desc->decode_nlri(s, nlri, len, a);

@@ -2446,6 +2450,7 @@ found:
static inline int
bgp_send(struct bgp_conn *conn, uint type, uint len)
{
  struct bgp_proto *p = conn->bgp;
  sock *sk = conn->sk;
  byte *buf = sk->tbuf;

@@ -2453,6 +2458,7 @@ bgp_send(struct bgp_conn *conn, uint type, uint len)
  put_u16(buf+16, len);
  buf[18] = type;

  STATS(tx_pkts[type - 1]);
  return sk_send(sk, len);
}

@@ -2812,13 +2818,22 @@ bgp_rx_keepalive(struct bgp_conn *conn)
static void
bgp_rx_packet(struct bgp_conn *conn, byte *pkt, uint len)
{
  struct bgp_proto *p = conn->bgp;
  byte type = pkt[18];

  DBG("BGP: Got packet %02x (%d bytes)\n", type, len);

  if (conn->bgp->p.mrtdump & MD_MESSAGES)
  if (p->p.mrtdump & MD_MESSAGES)
    mrt_dump_bgp_packet(conn, pkt, len);

  if (type < PKT_OPEN || type > PKT_ROUTE_REFRESH)
  {
    bgp_error(conn, 1, 3, pkt+18, 1);
    return;
  }

  STATS(rx_pkts[type - 1]);

  switch (type)
  {
  case PKT_OPEN:		return bgp_rx_open(conn, pkt, len);
@@ -2826,7 +2841,6 @@ bgp_rx_packet(struct bgp_conn *conn, byte *pkt, uint len)
  case PKT_NOTIFICATION:	return bgp_rx_notification(conn, pkt, len);
  case PKT_KEEPALIVE:		return bgp_rx_keepalive(conn);
  case PKT_ROUTE_REFRESH:	return bgp_rx_route_refresh(conn, pkt, len);
  default:			bgp_error(conn, 1, 3, pkt+18, 1);
  }
}

+2 −0
Original line number Diff line number Diff line
@@ -135,6 +135,8 @@ stat_route:

stat_route_item:
   cmd { *this_srt_last_cmd = $1; this_srt_last_cmd = &($1->next); }
 | PREFERENCE expr ';' { this_srt->preference = $2; check_u16($2); }
 | DISTANCE expr ';' { this_srt->preference = $2; check_u16($2); }
 ;

stat_route_opts:
Loading