s32 bgp_nlri_parse_6pe (struct peer *peer, struct attr *attr, struct bgp_nlri *packet) { u_char *pnt; u_char *lim; struct prefix p; int psize; int prefixlen; u_int32_t label; u_char *tagpnt; /* Check peer status. */ if (peer->status != Established) return 0; pnt = packet->nlri; lim = pnt + packet->length; for (; pnt < lim; pnt += psize) { /* Clear prefix structure. */ memset (&p, 0, sizeof (struct prefix)); /* Fetch prefix length. */ prefixlen = *pnt++; p.family = AF_INET6; psize = PSIZE (prefixlen); if (prefixlen < 24) { zlog_err ("prefix length is less than 88: %d", prefixlen); return -1; } label = decode_label (pnt); /* Copyr label to prefix. */ tagpnt = pnt; p.prefixlen = prefixlen - 24; memcpy (&p.u.prefix, pnt + 3, psize - 3); if (pnt + psize > lim) return -1; if (attr) bgp_update (peer, &p, attr, AFI_IP6, SAFI_UNICAST, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, tagpnt, 0); else bgp_withdraw (peer, &p, attr, AFI_IP6, SAFI_UNICAST, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, tagpnt); } /* Packet length consistency check. */ if (pnt != lim) return -1; return 0; }
s32 bgp_fec_announce_6pe(struct zclient *zc, struct prefix *p, struct bgp_info *info, struct bgp *bgp) { u32 flags = 0; struct stream * s = zc->obuf ; struct peer * peer = info->peer ; u32 gateway ,label ; struct rtm_fec_info_key key; struct in6_addr *nexthop = NULL; if( !info || !info->attr || !info->attr->extra ) return -1 ; if (info->attr->extra->mp_nexthop_len == 16) { nexthop = &info->attr->extra->mp_nexthop_global; } /* If both global and link-local address present. */ else if (info->attr->extra->mp_nexthop_len == 32) { /* Workaround for Cisco's nexthop bug. */ if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global) && peer->su_remote->sa.sa_family == AF_INET6) nexthop = &peer->su_remote->sin6.sin6_addr; else nexthop = &info->attr->extra->mp_nexthop_local; } if(NULL == nexthop || !IN6_IS_ADDR_V4MAPPED(nexthop)) { return -1; } memcpy (&gateway , ((s8 *)nexthop) + 12, 4); label = decode_label ( bgp_info_extra_get(info)->tag) ; SET_FLAG(flags, ZAPI_FEC_GATEWAY); stream_reset(s); zclient_create_header(s,ZEBRA_MPLS_FEC6_INFO_ADD); stream_put_prefix(s,p); stream_putl(s, flags); stream_putl(s, ZEBRA_FEC_TYPE_6PE); if( peer ) stream_putl(s,peer->nexthop.v4.s_addr); else stream_putl(s,0); // lsr_id = 0 stream_putl(s,label); stream_putl(s,gateway); stream_putw_at (s, 0, stream_get_endp (s)); key.peer_addr = gateway; return rtm_fec_send(ZEBRA_MPLS_FEC6_INFO_ADD, zc, p, s, &key) ; }
s32 bgp_fec_announce_6vpe(bgp_litevrf_config_t *litevrf, struct prefix *p, struct bgp_info *info) { u32 flags = 0; struct stream * s = zclient->obuf ; struct peer * peer = info->peer ; u32 gateway ,label ; struct rtm_fec_info_key key; struct in6_addr *nexthop = NULL; if( !info || !info->attr || !info->attr->extra ) return -1 ; nexthop = &info->attr->extra->mp_nexthop_global; if(NULL == nexthop || !IN6_IS_ADDR_V4MAPPED(nexthop)) { return -1; } memcpy (&gateway , ((s8 *)nexthop) + 12, 4); label = decode_label ( bgp_info_extra_get(info)->tag) ; SET_FLAG(flags, ZAPI_FEC_GATEWAY|ZAPI_FEC_LITEVRF); stream_reset(s); zclient_create_header(s,ZEBRA_MPLS_FEC6_INFO_ADD); stream_put_prefix(s,p); stream_putl(s, flags); stream_putl(s,litevrf->id); stream_putl(s, ZEBRA_FEC_TYPE_6VPE); if( peer ) stream_putl(s,peer->nexthop.v4.s_addr); else stream_putl(s,0); // lsr_id = 0 stream_putl(s,label); stream_putl(s,gateway); stream_putw_at (s, 0, stream_get_endp (s)); key.peer_addr = gateway; return rtm_fec_send(ZEBRA_MPLS_FEC6_INFO_ADD, zclient, p, s, &key) ; }
int xkas::eval_integer(const char *&s) { if(!*s) throw "nall::bad_eval_integer"; int value = 0, x = *s, y = *(s + 1); //label if(x == '.' || x == '_' || (x >= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z')) { const char *start = s; s += 1; for(;;) { if(*s == ':' || *s == '.' || *s == '_' || (*s >= 'A' && *s <= 'Z') || (*s >= 'a' && *s <= 'z') || (*s >= '0' && *s <= '9')) { s++; continue; } break; } string name; strlcpy(name, start, s - start + 1); if(decode_label(name) == false) throw "nall::bad_eval_integer"; unsigned offset; if(find_label(name, offset) == true) return offset; if(pass == 1) return 0; //label may not have been found in first pass (may occur later on) throw "nall::bad_eval_integer"; } //hexadecimal if(x == '$' || (x == '0' && (y == 'X' || y == 'x'))) { s += (x == '$' ? 1 : 2); for(;;) { if(*s >= '0' && *s <= '9') { value = value * 16 + (*s++ - '0'); continue; } if(*s >= 'A' && *s <= 'F') { value = value * 16 + (*s++ - 'A' + 10); continue; } if(*s >= 'a' && *s <= 'f') { value = value * 16 + (*s++ - 'a' + 10); continue; } return value; } } //binary if(x == '%' || (x == '0' && (y == 'B' || y == 'b'))) { s += (x == '%' ? 1 : 2); for(;;) { if(*s == '0' || *s == '1') { value = value * 2 + (*s++ - '0'); continue; } return value; } } //octal (or decimal '0') if(x == '0') { s += 1; for(;;) { if(*s >= '0' && *s <= '7') { value = value * 8 + (*s++ - '0'); continue; } return value; } } //decimal if(x >= '0' && x <= '9') { for(;;) { if(*s >= '0' && *s <= '9') { value = value * 10 + (*s++ - '0'); continue; } return value; } } //char if(x == '\'') { s += 1; value = state.table[*s++]; if(*s != '\'') throw "mismatched_char"; s += 1; return value; } throw "nall::bad_eval_integer"; }