Last active
June 30, 2024 15:01
-
-
Save toravir/7400f3e032089e19bf0804a870d025be to your computer and use it in GitHub Desktop.
VPP Install BGP Type 5 Route
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2.7 | |
from __future__ import print_function | |
import os | |
import fnmatch | |
import socket | |
from vpp_papi import VPP, mac_pton | |
CLIENT_ID = "Vppclient" | |
#yVPP_JSON_DIR = '/usr/share/vpp/api/core/' | |
API_TOP_DIR = '/root/Nov14/build-root/install-vpp_debug-native/vpp/share/vpp/api/' | |
API_FILE_SUFFIX = '*.api.json' | |
def load_json_api_files(json_dir, suffix=API_FILE_SUFFIX): | |
jsonfiles = [] | |
for root, dirnames, filenames in os.walk(json_dir): | |
for filename in fnmatch.filter(filenames, suffix): | |
jsonfiles.append(os.path.join(json_dir, filename)) | |
if not jsonfiles: | |
print('Error: no json api files found') | |
exit(-1) | |
return jsonfiles | |
def connect_vpp(jsonfiles): | |
vpp = VPP(jsonfiles) | |
r = vpp.connect("CLIENT_ID") | |
print("VPP api opened with code: %s" % r) | |
return vpp | |
gTableIds = 10 | |
def create_vrf(vrfName): | |
global gTableIds | |
gTableIds+=1 | |
rc = vpp.api.ip_table_add_del(is_add=1, table={'table_id':gTableIds, 'is_ip6':0, 'name':vrfName}) | |
print("IP Table Add/Del RC:", rc.retval) | |
return gTableIds | |
def newLoopback(vrf, inst, ip): | |
if inst is not None: | |
rc = vpp.api.create_loopback_instance(is_specified=1, user_instance=inst) | |
else: | |
rc = vpp.api.create_loopback_instance() | |
print("Create Loopback RC:", rc.retval) | |
ifIdx = rc.sw_if_index | |
rc = vpp.api.sw_interface_set_table(sw_if_index=ifIdx, is_ipv6=0, vrf_id=vrf) | |
print("set vrf for interface RC:", rc.retval) | |
if ip is not None: | |
rc = vpp.api.sw_interface_add_del_address( | |
sw_if_index=ifIdx, | |
is_add=1, | |
prefix={'address': {'af': 0, | |
'un': { 'ip4': socket.inet_aton(ip) } | |
}, | |
'len':32}) | |
print("set IP of ", ip, " on interface RC:", rc.retval) | |
rc = vpp.api.sw_interface_set_flags(sw_if_index=ifIdx, flags=1) | |
print("Bring up interface RC:", rc.retval) | |
return ifIdx | |
def newVxlanTunnel(vrf, src, dst, vnid): | |
rc = vpp.api.vxlan_add_del_tunnel(is_add=1, instance=vnid, | |
src_address=socket.inet_aton(src), | |
dst_address=socket.inet_aton(dst), | |
decap_next_index=0xffffffff, | |
vni=vnid) | |
tunIfIdx = rc.sw_if_index | |
rc = vpp.api.sw_interface_set_table(sw_if_index=tunIfIdx, is_ipv6=0, vrf_id=vrf) | |
print("set if table RC:", rc.retval) | |
rc = vpp.api.sw_interface_set_flags(sw_if_index=tunIfIdx, flags=1) | |
print("set if status RC:", rc.retval) | |
return tunIfIdx | |
def newBd(inst, mac, loopIf, tunIf): | |
rc = vpp.api.bridge_domain_add_del(is_add=1, bd_id=inst, forward=1) | |
print("create bd RC:", rc.retval) | |
rc = vpp.api.sw_interface_set_l2_bridge(rx_sw_if_index=loopIf, bd_id=inst, enable=1, port_type=1) | |
print("set BVI bd RC:", rc.retval) | |
rc = vpp.api.sw_interface_set_l2_bridge(rx_sw_if_index=tunIf, bd_id=inst, enable=1) | |
print("set l2 bd RC:", rc.retval) | |
rc = vpp.api.l2fib_add_del(is_add=1, mac=mac_pton(mac), bd_id=inst, sw_if_index=tunIf, static_mac=1) | |
print("set l2 fib RC:", rc.retval) | |
def addStaticArp(ip, ifIdx, mac): | |
rc = vpp.api.ip_neighbor_add_del(is_add=1, neighbor={'sw_if_index':ifIdx, | |
'ip_address': {'af': 0, | |
'un': { 'ip4': socket.inet_aton(ip) } | |
}, | |
'mac_address':mac, | |
'flags':1}) | |
print("set static arp RC:", rc.retval) | |
def setupXConnect(loopIf, tunIf, tnVrf, ip): | |
rc = vpp.api.sw_interface_set_l2_xconnect(rx_sw_if_index=loopIf, tx_sw_if_index=tunIf, enable=1) | |
print("set if xconnect RC:", rc.retval) | |
#rc = vpp.api.sw_interface_set_l2_xconnect(rx_sw_if_index=if2, tx_sw_if_index=if1, enable=1) | |
#print("set if xconnect RC:", rc.retval) | |
rc = vpp.api.sw_interface_add_del_address( | |
sw_if_index=loopIf, | |
is_add=1, | |
prefix={'address': {'af': 0, | |
'un': { 'ip4': socket.inet_aton(ip) } | |
}, | |
'len':32}) | |
print("set IP of ", ip, " on interface RC:", rc.retval) | |
lstack = [] | |
while (len(lstack) < 16): | |
lstack.append({}) | |
rc = vpp.api.l3xc_update(l3xc={'sw_if_index':tunIf, | |
'is_ip6':0, | |
'n_paths':1, | |
'paths':[{'sw_if_index':loopIf, | |
'table_id':0, | |
'nh' : {'address': {'ip4': socket.inet_aton(ip)}, | |
'obj_id':loopIf, | |
}, | |
'label_stack':lstack, | |
}] | |
}) | |
print("set l3xc RC:", rc.retval) | |
def create_type5_route (infraVrf, tnVrf, pfx, srcTep, dstTep, mac, vnid): | |
dummy_addr1 = "127.0.0.123" | |
dummy_addr2 = "127.0.0.100" | |
loopbackIfIdx = newLoopback(vrf=tnVrf, inst=vnid, ip=dummy_addr1) | |
#loop2 = newLoopback(vrf=tnVrf, inst=vnid+1, ip=None) | |
tunIfIdx = newVxlanTunnel(infraVrf, srcTep, dstTep, vnid) | |
newBd(vnid, mac, loopbackIfIdx, tunIfIdx) | |
addStaticArp(dummy_addr2, loopbackIfIdx, mac) | |
#setupXConnect(loopbackIfIdx, tunIfIdx, tnVrf, dummy_addr1) | |
lstack = [] | |
while (len(lstack) < 16): | |
lstack.append({}) | |
rc = vpp.api.ip_route_add_del(is_add=1, route={'table_id':tnVrf, | |
'prefix':pfx, | |
'n_paths':1, | |
'paths': [{'sw_if_index':loopbackIfIdx, | |
'table_id':tnVrf, | |
'nh' : {'address': {'ip4': socket.inet_aton(dummy_addr2)}, | |
'obj_id':loopbackIfIdx, | |
}, | |
'label_stack':lstack, | |
}] | |
}) | |
print("set route add RC:", rc.retval) | |
return | |
# Python apis need json definitions to interpret messages | |
vpp = connect_vpp(load_json_api_files(API_TOP_DIR+"core") + load_json_api_files(API_TOP_DIR+"plugins")) | |
#1. Setup Infra (Underlay) | |
#infraVrf = create_vrf("infra") | |
infraVrf = 0 | |
#infra - srcTep | |
srcTepIf = newLoopback(infraVrf, None, "100.100.100.100") | |
#2. Setup Tenant (Overlay) | |
tnVrf = create_vrf("t0:ctx1") | |
#3. Create Route in tenant | |
create_type5_route(infraVrf, tnVrf, pfx="10.0.0.0/24", | |
srcTep="100.100.100.100", | |
dstTep="200.200.200.200", | |
mac="aa:bb:cc:dd:ee:ff", | |
vnid=11223) | |
#create_tunnel() | |
exit(vpp.disconnect()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
create packet-generator interface pg0 | |
set interface ip table pg0 11 | |
set interface state pg0 up | |
set int ip address pg0 1.1.20.2/24 | |
set ip arp pg0 1.1.20.20 f0:0d:f0:0d:f0:0d static | |
create packet-generator interface pg1 | |
set interface ip table pg1 0 | |
set int state pg1 up | |
set int ip address pg1 3.3.3.1/24 | |
set ip arp pg1 3.3.3.3 a1:b1:c1:d1:e1:f1 static | |
ip route add 200.200.200.200/32 table 0 via 3.3.3.3 pg1 | |
trace add pg-input 100 | |
packet-generator enable | |
#Encap | |
packet-generator new { name x limit 1 node ethernet-input size 64-64 interface pg0 data { IP4: 1.2.3 -> 4.5.6 ICMP: 1.1.20.20 -> 10.0.0.10 ICMP echo_request incrementing 100 } } | |
#Decap | |
packet-generator new { name reply limit 1 node ethernet-input size 114-114 interface pg1 data { hex 0x02feadc6de86a1b1c1d1e1f108004500006400000000fd11632fc8c8c8c864646464722312b50050000008000000002bd700dead000000d7aabbccddeeff080045000032000000003f015cad0a00000a010114140800d9db000102030405060708090a0b0c0d0e0f10111213141516171819 } } | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DBGvpp# show trace ------------------- Start of thread 0 vpp_main ------------------- | |
Packet 1 | |
00:00:44:103302: pg-input | |
stream x, 64 bytes, sw_if_index 5 | |
current data 0, length 64, buffer-pool 0, ref-count 1, trace handle 0x0 | |
IP4: 00:01:00:02:00:03 -> 00:04:00:05:00:06 | |
ICMP: 1.1.20.20 -> 10.0.0.10 | |
tos 0x00, ttl 64, length 50, checksum 0x5bad | |
fragment id 0x0000 | |
ICMP echo_request checksum 0xd9db | |
00:00:44:103353: ethernet-input | |
frame: flags 0x1, hw-if-index 5, sw-if-index 5 | |
IP4: 00:01:00:02:00:03 -> 00:04:00:05:00:06 | |
00:00:44:103390: ip4-input | |
ICMP: 1.1.20.20 -> 10.0.0.10 | |
tos 0x00, ttl 64, length 50, checksum 0x5bad | |
fragment id 0x0000 | |
ICMP echo_request checksum 0xd9db | |
00:00:44:103405: ip4-lookup | |
fib 1 dpo-idx 0 flow hash: 0x00000000 | |
ICMP: 1.1.20.20 -> 10.0.0.10 | |
tos 0x00, ttl 64, length 50, checksum 0x5bad | |
fragment id 0x0000 | |
ICMP echo_request checksum 0xd9db | |
00:00:44:103421: ip4-rewrite | |
tx_sw_if_index 3 dpo-idx 0 : ipv4 via 127.0.0.100 loop11223: mtu:9000 aabbccddeeffdead000000d70800 flow hash: 0x00000000 | |
00000000: aabbccddeeffdead000000d7080045000032000000003f015cad010114140a00 | |
00000020: 000a0800d9db000102030405060708090a0b0c0d0e0f101112131415 | |
00:00:44:103434: loop11223-output | |
loop11223 l2_hdr_offset_valid l3_hdr_offset_valid | |
IP4: de:ad:00:00:00:d7 -> aa:bb:cc:dd:ee:ff | |
ICMP: 1.1.20.20 -> 10.0.0.10 | |
tos 0x00, ttl 63, length 50, checksum 0x5cad | |
fragment id 0x0000 | |
ICMP echo_request checksum 0xd9db | |
00:00:44:103485: l2-input | |
l2-input: sw_if_index 3 dst aa:bb:cc:dd:ee:ff src de:ad:00:00:00:d7 | |
00:00:44:103493: l2-fwd | |
l2-fwd: sw_if_index 3 dst aa:bb:cc:dd:ee:ff src de:ad:00:00:00:d7 bd_index 1 result [0x300000004, 4] static age-not | |
00:00:44:103502: l2-output | |
l2-output: sw_if_index 4 dst aa:bb:cc:dd:ee:ff src de:ad:00:00:00:d7 data 08 00 45 00 00 32 00 00 00 00 3f 01 | |
00:00:44:103511: vxlan4-encap | |
VXLAN encap to vxlan_tunnel0 vni 11223 | |
00:00:44:103520: ip4-rewrite | |
tx_sw_if_index 6 dpo-idx 4 : ipv4 via 3.3.3.3 pg1: mtu:9000 a1b1c1d1e1f102fef53f9c3a0800 flow hash: 0x0000000e | |
00000000: a1b1c1d1e1f102fef53f9c3a08004500006400000000fd11632f64646464c8c8 | |
00000020: c8c8722312b50050000008000000002bd700aabbccddeeffdead0000 | |
00:00:44:103525: pg1-output | |
pg1 l2_hdr_offset_valid l3_hdr_offset_valid | |
IP4: 02:fe:f5:3f:9c:3a -> a1:b1:c1:d1:e1:f1 | |
UDP: 100.100.100.100 -> 200.200.200.200 | |
tos 0x00, ttl 253, length 100, checksum 0x632f | |
fragment id 0x0000 | |
UDP: 29219 -> 4789 | |
length 80, checksum 0x0000 | |
00:00:44:103530: pg1-tx | |
buffer 0x9ffd4: current data -50, length 114, buffer-pool 0, ref-count 1, trace handle 0x0 | |
l2-hdr-offset 0 l3-hdr-offset 14 | |
IP4: 02:fe:f5:3f:9c:3a -> a1:b1:c1:d1:e1:f1 | |
UDP: 100.100.100.100 -> 200.200.200.200 | |
tos 0x00, ttl 253, length 100, checksum 0x632f | |
fragment id 0x0000 | |
UDP: 29219 -> 4789 | |
length 80, checksum 0x0000 | |
Packet 2 | |
00:00:44:103302: pg-input | |
stream reply, 114 bytes, sw_if_index 6 | |
current data 0, length 114, buffer-pool 0, ref-count 1, trace handle 0x1 | |
IP4: a1:b1:c1:d1:e1:f1 -> 02:fe:ad:c6:de:86 | |
UDP: 200.200.200.200 -> 100.100.100.100 | |
tos 0x00, ttl 253, length 100, checksum 0x632f | |
fragment id 0x0000 | |
UDP: 29219 -> 4789 | |
length 80, checksum 0x0000 | |
00:00:44:103390: ip4-input | |
UDP: 200.200.200.200 -> 100.100.100.100 | |
tos 0x00, ttl 253, length 100, checksum 0x632f | |
fragment id 0x0000 | |
UDP: 29219 -> 4789 | |
length 80, checksum 0x0000 | |
00:00:44:103405: ip4-lookup | |
fib 0 dpo-idx 5 flow hash: 0x00000000 | |
UDP: 200.200.200.200 -> 100.100.100.100 | |
tos 0x00, ttl 253, length 100, checksum 0x632f | |
fragment id 0x0000 | |
UDP: 29219 -> 4789 | |
length 80, checksum 0x0000 | |
00:00:44:103427: ip4-local | |
UDP: 200.200.200.200 -> 100.100.100.100 | |
tos 0x00, ttl 253, length 100, checksum 0x632f | |
fragment id 0x0000 | |
UDP: 29219 -> 4789 | |
length 80, checksum 0x0000 | |
00:00:44:103445: ip4-udp-lookup | |
UDP: src-port 29219 dst-port 4789 | |
00:00:44:103478: vxlan4-input | |
VXLAN decap from vxlan_tunnel0 vni 11223 next 1 error 0 | |
00:00:44:103485: l2-input | |
l2-input: sw_if_index 4 dst de:ad:00:00:00:d7 src aa:bb:cc:dd:ee:ff | |
00:00:44:103493: l2-fwd | |
l2-fwd: sw_if_index 4 dst de:ad:00:00:00:d7 src aa:bb:cc:dd:ee:ff bd_index 1 result [0x700000003, 3] static age-not bvi | |
00:00:44:103507: ip4-input | |
ICMP: 10.0.0.10 -> 1.1.20.20 | |
tos 0x00, ttl 63, length 50, checksum 0x5cad | |
fragment id 0x0000 | |
ICMP echo_request checksum 0xd9db | |
00:00:44:103517: ip4-lookup | |
fib 1 dpo-idx 2 flow hash: 0x00000000 | |
ICMP: 10.0.0.10 -> 1.1.20.20 | |
tos 0x00, ttl 63, length 50, checksum 0x5cad | |
fragment id 0x0000 | |
ICMP echo_request checksum 0xd9db | |
00:00:44:103520: ip4-rewrite | |
tx_sw_if_index 5 dpo-idx 2 : ipv4 via 1.1.20.20 pg0: mtu:9000 f00df00df00d02fe89bb0a860800 flow hash: 0x00000000 | |
00000000: f00df00df00d02fe89bb0a86080045000032000000003e015dad0a00000a0101 | |
00000020: 14140800d9db000102030405060708090a0b0c0d0e0f101112131415 | |
00:00:44:103528: pg0-output | |
pg0 l4-cksum-computed l4-cksum-correct l2_hdr_offset_valid l3_hdr_offset_valid | |
IP4: 02:fe:89:bb:0a:86 -> f0:0d:f0:0d:f0:0d | |
ICMP: 10.0.0.10 -> 1.1.20.20 | |
tos 0x00, ttl 62, length 50, checksum 0x5dad | |
fragment id 0x0000 | |
ICMP echo_request checksum 0xd9db | |
00:00:44:103536: pg0-tx | |
buffer 0x9ffad: current data 50, length 64, buffer-pool 0, ref-count 1, trace handle 0x1 | |
l4-cksum-computed l4-cksum-correct l2-hdr-offset 50 l3-hdr-offset 14 | |
IP4: 02:fe:89:bb:0a:86 -> f0:0d:f0:0d:f0:0d | |
ICMP: 10.0.0.10 -> 1.1.20.20 | |
tos 0x00, ttl 62, length 50, checksum 0x5dad | |
fragment id 0x0000 | |
ICMP echo_request checksum 0xd9db | |
DBGvpp# |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment