1 # Copyright (C) 2013,2014 Nippon Telegraph and Telephone Corporation.
2 # Copyright (C) 2013,2014 YAMAMOTO Takashi <yamamoto at valinux co jp>
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 from __future__ import print_function
24 from nose.tools import eq_
25 from nose.tools import ok_
27 from ryu.utils import binary_str
28 from ryu.lib import pcaplib
29 from ryu.lib.packet import packet
30 from ryu.lib.packet import bgp
31 from ryu.lib.packet import afi
32 from ryu.lib.packet import safi
35 LOG = logging.getLogger(__name__)
37 BGP4_PACKET_DATA_DIR = os.path.join(
38 os.path.dirname(sys.modules[__name__].__file__), '../../packet_data/bgp4/')
40 PMSI_TYPE_NO_TUNNEL_INFORMATION_PRESENT = (
41 bgp.BGPPathAttributePmsiTunnel.TYPE_NO_TUNNEL_INFORMATION_PRESENT
43 PMSI_TYPE_INGRESS_REPLICATION = (
44 bgp.BGPPathAttributePmsiTunnel.TYPE_INGRESS_REPLICATION
50 operator=(bgp.FlowSpecPort.GT | bgp.FlowSpecPort.EQ),
54 operator=(bgp.FlowSpecPort.AND | bgp.FlowSpecPort.LT |
58 bgp.FlowSpecPort(operator=bgp.FlowSpecPort.EQ, value=80),
60 bgp.FlowSpecDestPort(operator=bgp.FlowSpecDestPort.EQ, value=8080),
62 bgp.FlowSpecDestPort(operator=bgp.FlowSpecDestPort.GT, value=9000),
65 operator=(bgp.FlowSpecDestPort.AND | bgp.FlowSpecDestPort.LT),
69 operator=(bgp.FlowSpecDestPort.LT | bgp.FlowSpecDestPort.EQ),
73 operator=(bgp.FlowSpecSrcPort.LT | bgp.FlowSpecSrcPort.EQ),
77 operator=(bgp.FlowSpecSrcPort.AND | bgp.FlowSpecSrcPort.GT |
78 bgp.FlowSpecSrcPort.EQ),
82 operator=bgp.FlowSpecSrcPort.LT, value=10100),
85 operator=(bgp.FlowSpecSrcPort.AND | bgp.FlowSpecSrcPort.GT),
88 bgp.FlowSpecIcmpType(operator=bgp.FlowSpecIcmpType.EQ, value=0),
90 bgp.FlowSpecIcmpCode(operator=bgp.FlowSpecIcmpCode.EQ, value=6),
93 operator=0, # Partial match
94 value=(bgp.FlowSpecTCPFlags.SYN | bgp.FlowSpecTCPFlags.ACK)),
95 # tcp_flags='&!=URGENT'
97 operator=(bgp.FlowSpecTCPFlags.AND | bgp.FlowSpecTCPFlags.NOT),
98 value=bgp.FlowSpecTCPFlags.URGENT),
100 bgp.FlowSpecPacketLen(
101 operator=bgp.FlowSpecPacketLen.EQ, value=1000),
103 bgp.FlowSpecPacketLen(
104 operator=(bgp.FlowSpecTCPFlags.AND | bgp.FlowSpecPacketLen.EQ),
107 bgp.FlowSpecDSCP(operator=bgp.FlowSpecDSCP.EQ, value=22),
109 bgp.FlowSpecDSCP(operator=bgp.FlowSpecDSCP.EQ, value=24),
114 bgp.FlowSpecEtherType(operator=bgp.FlowSpecEtherType.EQ, value=0x0800),
115 # source_mac='12:34:56:78:90:AB'
116 bgp.FlowSpecSourceMac(addr='12:34:56:78:90:AB', length=6),
117 # dest_mac='DE:EF:C0:FF:EE:DD'
118 bgp.FlowSpecDestinationMac(addr='BE:EF:C0:FF:EE:DD', length=6),
120 bgp.FlowSpecLLCDSAP(operator=bgp.FlowSpecLLCDSAP.EQ, value=0x42),
122 bgp.FlowSpecLLCSSAP(operator=bgp.FlowSpecLLCSSAP.EQ, value=0x42),
124 bgp.FlowSpecLLCControl(operator=bgp.FlowSpecLLCControl.EQ, value=100),
126 bgp.FlowSpecSNAP(operator=bgp.FlowSpecSNAP.EQ, value=0x12345),
128 bgp.FlowSpecVLANID(operator=bgp.FlowSpecVLANID.GT, value=4000),
131 operator=(bgp.FlowSpecVLANCoS.GT | bgp.FlowSpecVLANCoS.EQ), value=3),
132 # inner_vlan_id='<3000'
133 bgp.FlowSpecInnerVLANID(operator=bgp.FlowSpecInnerVLANID.LT, value=3000),
134 # inner_vlan_cos='<=5'
135 bgp.FlowSpecInnerVLANCoS(
136 operator=(bgp.FlowSpecInnerVLANCoS.LT | bgp.FlowSpecInnerVLANCoS.EQ),
141 class Test_bgp(unittest.TestCase):
142 """ Test case for ryu.lib.packet.bgp
151 def test_open1(self):
152 msg = bgp.BGPOpen(my_as=30000, bgp_identifier='192.0.2.1')
153 binmsg = msg.serialize()
154 msg2, _, rest = bgp.BGPMessage.parser(binmsg)
155 eq_(str(msg), str(msg2))
159 def test_open2(self):
160 opt_param = [bgp.BGPOptParamCapabilityUnknown(cap_code=200,
162 bgp.BGPOptParamCapabilityGracefulRestart(flags=0,
165 bgp.BGPOptParamCapabilityRouteRefresh(),
166 bgp.BGPOptParamCapabilityCiscoRouteRefresh(),
167 bgp.BGPOptParamCapabilityMultiprotocol(
168 afi=afi.IP, safi=safi.MPLS_VPN),
169 bgp.BGPOptParamCapabilityCarryingLabelInfo(),
170 bgp.BGPOptParamCapabilityFourOctetAsNumber(
172 bgp.BGPOptParamUnknown(type_=99, value=b'fuga')]
173 msg = bgp.BGPOpen(my_as=30000, bgp_identifier='192.0.2.2',
175 binmsg = msg.serialize()
176 msg2, _, rest = bgp.BGPMessage.parser(binmsg)
177 eq_(str(msg), str(msg2))
181 def test_update1(self):
182 msg = bgp.BGPUpdate()
183 binmsg = msg.serialize()
184 msg2, _, rest = bgp.BGPMessage.parser(binmsg)
185 eq_(str(msg), str(msg2))
189 def test_update2(self):
190 withdrawn_routes = [bgp.BGPWithdrawnRoute(length=0,
192 bgp.BGPWithdrawnRoute(length=1,
194 bgp.BGPWithdrawnRoute(length=3,
196 bgp.BGPWithdrawnRoute(length=7,
198 bgp.BGPWithdrawnRoute(length=32,
201 bgp.LabelledVPNIPAddrPrefix(24, '192.0.9.0',
202 route_dist='100:100',
204 bgp.LabelledVPNIPAddrPrefix(26, '192.0.10.192',
205 route_dist='10.0.0.1:10000',
206 labels=[5, 6, 7, 8]),
209 bgp.LabelledIPAddrPrefix(24, '192.168.0.0', labels=[1, 2, 3])
212 bgp.LabelledVPNIP6AddrPrefix(64, '2001:db8:1111::',
213 route_dist='200:200',
215 bgp.LabelledVPNIP6AddrPrefix(64, '2001:db8:2222::',
216 route_dist='10.0.0.1:10000',
217 labels=[5, 6, 7, 8]),
220 bgp.LabelledIP6AddrPrefix(64, '2001:db8:3333::', labels=[1, 2, 3])
223 bgp.BGP_COMMUNITY_NO_EXPORT,
224 bgp.BGP_COMMUNITY_NO_ADVERTISE,
227 bgp.BGPTwoOctetAsSpecificExtendedCommunity(
228 subtype=1, as_number=65500, local_administrator=3908876543),
229 bgp.BGPFourOctetAsSpecificExtendedCommunity(
230 subtype=2, as_number=10000000, local_administrator=59876),
231 bgp.BGPIPv4AddressSpecificExtendedCommunity(
232 subtype=3, ipv4_address='192.0.2.1',
233 local_administrator=65432),
234 bgp.BGPOpaqueExtendedCommunity(subtype=13, opaque=b'abcdef'),
235 bgp.BGPEncapsulationExtendedCommunity(
236 subtype=0x0c, tunnel_type=10),
237 bgp.BGPEvpnMacMobilityExtendedCommunity(
238 subtype=0, flags=0xff, sequence_number=0x11223344),
239 bgp.BGPEvpnEsiLabelExtendedCommunity(
240 subtype=1, flags=0xff, label=b'\xFF\xFF\xFF'),
241 bgp.BGPEvpnEsiLabelExtendedCommunity(
242 subtype=1, flags=0xff, mpls_label=0xfffff),
243 bgp.BGPEvpnEsiLabelExtendedCommunity(
244 subtype=1, flags=0xff, vni=0xffffff),
245 bgp.BGPEvpnEsImportRTExtendedCommunity(
246 subtype=2, es_import="aa:bb:cc:dd:ee:ff"),
247 bgp.BGPUnknownExtendedCommunity(type_=99, value=b'abcdefg'),
250 bgp.BGPPathAttributeOrigin(value=1),
251 bgp.BGPPathAttributeAsPath(value=[[1000], {1001, 1002},
253 bgp.BGPPathAttributeNextHop(value='192.0.2.199'),
254 bgp.BGPPathAttributeMultiExitDisc(value=2000000000),
255 bgp.BGPPathAttributeLocalPref(value=1000000000),
256 bgp.BGPPathAttributeAtomicAggregate(),
257 bgp.BGPPathAttributeAggregator(as_number=40000,
259 bgp.BGPPathAttributeCommunities(communities=communities),
260 bgp.BGPPathAttributeOriginatorId(value='10.1.1.1'),
261 bgp.BGPPathAttributeClusterList(value=['1.1.1.1', '2.2.2.2']),
262 bgp.BGPPathAttributeExtendedCommunities(communities=ecommunities),
263 bgp.BGPPathAttributePmsiTunnel(
265 tunnel_type=PMSI_TYPE_NO_TUNNEL_INFORMATION_PRESENT,
266 label=b'\xFF\xFF\xFF'),
267 bgp.BGPPathAttributePmsiTunnel(
269 tunnel_type=PMSI_TYPE_NO_TUNNEL_INFORMATION_PRESENT,
271 bgp.BGPPathAttributePmsiTunnel(
273 tunnel_type=PMSI_TYPE_INGRESS_REPLICATION,
275 tunnel_id=bgp.PmsiTunnelIdIngressReplication(
276 tunnel_endpoint_ip="1.1.1.1")),
277 bgp.BGPPathAttributePmsiTunnel(
279 tunnel_type=PMSI_TYPE_INGRESS_REPLICATION,
281 tunnel_id=bgp.PmsiTunnelIdIngressReplication(
282 tunnel_endpoint_ip="aa:bb:cc::dd:ee:ff")),
283 bgp.BGPPathAttributePmsiTunnel(
286 label=b'\xFF\xFF\xFF',
287 tunnel_id=bgp.PmsiTunnelIdUnknown(value=b'test')),
288 bgp.BGPPathAttributeAs4Path(value=[[1000000], {1000001, 1002},
290 bgp.BGPPathAttributeAs4Aggregator(as_number=100040000,
292 bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP, safi=safi.MPLS_VPN,
295 bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP, safi=safi.MPLS_LABEL,
298 bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP6, safi=safi.MPLS_VPN,
299 next_hop=['2001:db8::1'],
301 bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP6, safi=safi.MPLS_LABEL,
302 next_hop=['2001:db8::1',
305 bgp.BGPPathAttributeMpUnreachNLRI(afi=afi.IP, safi=safi.MPLS_VPN,
306 withdrawn_routes=mp_nlri),
307 bgp.BGPPathAttributeUnknown(flags=0, type_=100, value=300 * b'bar')
310 bgp.BGPNLRI(length=24, addr='203.0.113.1'),
311 bgp.BGPNLRI(length=16, addr='203.0.113.0')
313 msg = bgp.BGPUpdate(withdrawn_routes=withdrawn_routes,
314 path_attributes=path_attributes,
316 binmsg = msg.serialize()
317 msg2, _, rest = bgp.BGPMessage.parser(binmsg)
318 eq_(str(msg), str(msg2))
322 def test_keepalive(self):
323 msg = bgp.BGPKeepAlive()
324 binmsg = msg.serialize()
325 msg2, _, rest = bgp.BGPMessage.parser(binmsg)
326 eq_(str(msg), str(msg2))
330 def test_notification(self):
332 msg = bgp.BGPNotification(error_code=1, error_subcode=2, data=data)
333 binmsg = msg.serialize()
334 msg2, _, rest = bgp.BGPMessage.parser(binmsg)
335 eq_(str(msg), str(msg2))
336 eq_(len(msg), 21 + len(data))
339 def test_route_refresh(self):
340 msg = bgp.BGPRouteRefresh(afi=afi.IP, safi=safi.MPLS_VPN)
341 binmsg = msg.serialize()
342 msg2, _, rest = bgp.BGPMessage.parser(binmsg)
343 eq_(str(msg), str(msg2))
347 def test_stream_parser(self):
349 bgp.BGPNotification(error_code=1, error_subcode=2, data=b'foo'),
350 bgp.BGPNotification(error_code=3, error_subcode=4, data=b'bar'),
351 bgp.BGPNotification(error_code=5, error_subcode=6, data=b'baz'),
353 binmsgs = b''.join([bytes(msg.serialize()) for msg in msgs])
354 sp = bgp.StreamParser()
357 for m in sp.parse(b):
359 eq_(str(results), str(msgs))
361 def test_parser(self):
368 'evpn_esi_arbitrary',
370 'evpn_esi_l2_bridge',
372 'evpn_esi_router_id',
375 'evpn_nlri_mac_ip_ad',
376 'evpn_nlri_inc_multi_eth_tag',
378 'evpn_nlri_ip_prefix',
379 'flowspec_nlri_ipv4',
380 'flowspec_nlri_vpn4',
381 'flowspec_nlri_ipv6',
382 'flowspec_nlri_vpn6',
383 'flowspec_nlri_l2vpn',
384 'flowspec_action_traffic_rate',
385 'flowspec_action_traffic_action',
386 'flowspec_action_redirect',
387 'flowspec_action_traffic_marking',
391 LOG.debug('*** testing %s ...', f)
392 for _, buf in pcaplib.Reader(
393 open(BGP4_PACKET_DATA_DIR + f + '.pcap', 'rb')):
394 # Checks if BGP message can be parsed as expected.
395 pkt = packet.Packet(buf)
396 ok_(isinstance(pkt.protocols[-1], bgp.BGPMessage),
397 'Failed to parse BGP message: %s' % pkt)
399 # Checks if BGP message can be serialized as expected.
402 "b'%s' != b'%s'" % (binary_str(buf), binary_str(pkt.data)))
404 def test_vlan_action_parser(self):
405 action = bgp.BGPFlowSpecVlanActionCommunity(
406 actions_1=(bgp.BGPFlowSpecVlanActionCommunity.POP |
407 bgp.BGPFlowSpecVlanActionCommunity.SWAP),
410 actions_2=bgp.BGPFlowSpecVlanActionCommunity.PUSH,
414 binmsg = action.serialize()
415 msg, rest = bgp.BGPFlowSpecVlanActionCommunity.parse(binmsg)
416 eq_(str(action), str(msg))
419 def test_tpid_action_parser(self):
420 action = bgp.BGPFlowSpecTPIDActionCommunity(
421 actions=(bgp.BGPFlowSpecTPIDActionCommunity.TI |
422 bgp.BGPFlowSpecTPIDActionCommunity.TO),
426 binmsg = action.serialize()
427 msg, rest = bgp.BGPFlowSpecTPIDActionCommunity.parse(binmsg)
428 eq_(str(action), str(msg))
431 def test_json1(self):
432 opt_param = [bgp.BGPOptParamCapabilityUnknown(cap_code=200,
434 bgp.BGPOptParamCapabilityRouteRefresh(),
435 bgp.BGPOptParamCapabilityMultiprotocol(
436 afi=afi.IP, safi=safi.MPLS_VPN),
437 bgp.BGPOptParamCapabilityFourOctetAsNumber(
439 bgp.BGPOptParamUnknown(type_=99, value=b'fuga')]
440 msg1 = bgp.BGPOpen(my_as=30000, bgp_identifier='192.0.2.2',
442 jsondict = msg1.to_jsondict()
443 msg2 = bgp.BGPOpen.from_jsondict(jsondict['BGPOpen'])
444 eq_(str(msg1), str(msg2))
446 def test_json2(self):
447 withdrawn_routes = [bgp.BGPWithdrawnRoute(length=0,
449 bgp.BGPWithdrawnRoute(length=1,
451 bgp.BGPWithdrawnRoute(length=3,
453 bgp.BGPWithdrawnRoute(length=7,
455 bgp.BGPWithdrawnRoute(length=32,
458 bgp.LabelledVPNIPAddrPrefix(24, '192.0.9.0',
459 route_dist='100:100',
461 bgp.LabelledVPNIPAddrPrefix(26, '192.0.10.192',
462 route_dist='10.0.0.1:10000',
463 labels=[5, 6, 7, 8]),
466 bgp.LabelledIPAddrPrefix(24, '192.168.0.0', labels=[1, 2, 3])
469 bgp.LabelledVPNIP6AddrPrefix(64, '2001:db8:1111::',
470 route_dist='200:200',
472 bgp.LabelledVPNIP6AddrPrefix(64, '2001:db8:2222::',
473 route_dist='10.0.0.1:10000',
474 labels=[5, 6, 7, 8]),
477 bgp.LabelledIP6AddrPrefix(64, '2001:db8:3333::', labels=[1, 2, 3])
480 bgp.BGP_COMMUNITY_NO_EXPORT,
481 bgp.BGP_COMMUNITY_NO_ADVERTISE,
484 bgp.BGPTwoOctetAsSpecificExtendedCommunity(
485 subtype=1, as_number=65500, local_administrator=3908876543),
486 bgp.BGPFourOctetAsSpecificExtendedCommunity(
487 subtype=2, as_number=10000000, local_administrator=59876),
488 bgp.BGPIPv4AddressSpecificExtendedCommunity(
489 subtype=3, ipv4_address='192.0.2.1',
490 local_administrator=65432),
491 bgp.BGPOpaqueExtendedCommunity(subtype=13, opaque=b'abcdef'),
492 bgp.BGPEncapsulationExtendedCommunity(
493 subtype=0x0c, tunnel_type=10),
494 bgp.BGPEvpnMacMobilityExtendedCommunity(
495 subtype=0, flags=0xff, sequence_number=0x11223344),
496 bgp.BGPEvpnEsiLabelExtendedCommunity(
497 subtype=1, flags=0xff, label=b'\xFF\xFF\xFF'),
498 bgp.BGPEvpnEsiLabelExtendedCommunity(
499 subtype=1, flags=0xff, mpls_label=0xfffff),
500 bgp.BGPEvpnEsiLabelExtendedCommunity(
501 subtype=1, flags=0xff, vni=0xffffff),
502 bgp.BGPEvpnEsImportRTExtendedCommunity(
503 subtype=2, es_import="aa:bb:cc:dd:ee:ff"),
504 bgp.BGPUnknownExtendedCommunity(type_=99, value=b'abcdefg'),
507 bgp.BGPPathAttributeOrigin(value=1),
508 bgp.BGPPathAttributeAsPath(value=[[1000], {1001, 1002},
510 bgp.BGPPathAttributeNextHop(value='192.0.2.199'),
511 bgp.BGPPathAttributeMultiExitDisc(value=2000000000),
512 bgp.BGPPathAttributeLocalPref(value=1000000000),
513 bgp.BGPPathAttributeAtomicAggregate(),
514 bgp.BGPPathAttributeAggregator(as_number=40000,
516 bgp.BGPPathAttributeCommunities(communities=communities),
517 bgp.BGPPathAttributeExtendedCommunities(communities=ecommunities),
518 bgp.BGPPathAttributePmsiTunnel(
520 tunnel_type=PMSI_TYPE_NO_TUNNEL_INFORMATION_PRESENT,
521 label=b'\xFF\xFF\xFF'),
522 bgp.BGPPathAttributePmsiTunnel(
524 tunnel_type=PMSI_TYPE_NO_TUNNEL_INFORMATION_PRESENT,
526 bgp.BGPPathAttributePmsiTunnel(
528 tunnel_type=PMSI_TYPE_INGRESS_REPLICATION,
530 tunnel_id=bgp.PmsiTunnelIdIngressReplication(
531 tunnel_endpoint_ip="1.1.1.1")),
532 bgp.BGPPathAttributePmsiTunnel(
534 tunnel_type=PMSI_TYPE_INGRESS_REPLICATION,
536 tunnel_id=bgp.PmsiTunnelIdIngressReplication(
537 tunnel_endpoint_ip="aa:bb:cc::dd:ee:ff")),
538 bgp.BGPPathAttributePmsiTunnel(
541 label=b'\xFF\xFF\xFF',
542 tunnel_id=bgp.PmsiTunnelIdUnknown(value=b'test')),
543 bgp.BGPPathAttributeAs4Path(value=[[1000000], {1000001, 1002},
545 bgp.BGPPathAttributeAs4Aggregator(as_number=100040000,
547 bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP, safi=safi.MPLS_VPN,
550 bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP, safi=safi.MPLS_LABEL,
553 bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP6, safi=safi.MPLS_VPN,
554 next_hop=['2001:db8::1'],
556 bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP6, safi=safi.MPLS_LABEL,
557 next_hop=['2001:db8::1',
560 bgp.BGPPathAttributeMpUnreachNLRI(afi=afi.IP, safi=safi.MPLS_VPN,
561 withdrawn_routes=mp_nlri),
562 bgp.BGPPathAttributeUnknown(flags=0, type_=100, value=300 * b'bar')
565 bgp.BGPNLRI(length=24, addr='203.0.113.1'),
566 bgp.BGPNLRI(length=16, addr='203.0.113.0')
568 msg1 = bgp.BGPUpdate(withdrawn_routes=withdrawn_routes,
569 path_attributes=path_attributes,
571 jsondict = msg1.to_jsondict()
572 msg2 = bgp.BGPUpdate.from_jsondict(jsondict['BGPUpdate'])
573 eq_(str(msg1), str(msg2))
575 def test_flowspec_user_interface_ipv4(self):
576 rules = RULES_BASE + [
577 # dst_prefix='10.0.0.0/24
578 bgp.FlowSpecDestPrefix(addr='10.0.0.0', length=24),
579 # src_prefix='20.0.0.1/24'
580 bgp.FlowSpecSrcPrefix(addr='20.0.0.0', length=24),
582 bgp.FlowSpecIPProtocol(
583 operator=bgp.FlowSpecIPProtocol.EQ, value=6),
585 bgp.FlowSpecFragment(
586 operator=0, # Partial match
587 value=bgp.FlowSpecFragment.LF),
589 bgp.FlowSpecFragment(
590 operator=bgp.FlowSpecFragment.MATCH,
591 value=bgp.FlowSpecFragment.FF),
593 bgp.FlowSpecFragment(
594 operator=(bgp.FlowSpecFragment.AND |
595 bgp.FlowSpecFragment.MATCH),
596 value=bgp.FlowSpecFragment.ISF),
598 bgp.FlowSpecFragment(
599 operator=bgp.FlowSpecFragment.NOT,
600 value=bgp.FlowSpecFragment.DF)
603 msg = bgp.FlowSpecIPv4NLRI.from_user(
604 dst_prefix='10.0.0.0/24',
605 src_prefix='20.0.0.0/24',
607 port='>=8000 & <=9000 | ==80',
608 dst_port='8080 >9000&<9050 | <=1000',
609 src_port='<=9090 & >=9080 <10100 & >10000',
612 tcp_flags='SYN+ACK & !=URGENT',
613 packet_len='1000 & 1100',
615 fragment='LF ==FF&==ISF | !=DF')
616 msg2 = bgp.FlowSpecIPv4NLRI(rules=rules)
617 binmsg = msg.serialize()
618 binmsg2 = msg2.serialize()
619 eq_(str(msg), str(msg2))
620 eq_(binary_str(binmsg), binary_str(binmsg2))
621 msg3, rest = bgp.FlowSpecIPv4NLRI.parser(binmsg)
622 eq_(str(msg), str(msg3))
625 def test_flowspec_user_interface_vpv4(self):
626 rules = RULES_BASE + [
627 # dst_prefix='10.0.0.0/24
628 bgp.FlowSpecDestPrefix(addr='10.0.0.0', length=24),
629 # src_prefix='20.0.0.1/24'
630 bgp.FlowSpecSrcPrefix(addr='20.0.0.0', length=24),
632 bgp.FlowSpecIPProtocol(
633 operator=bgp.FlowSpecIPProtocol.EQ, value=6),
635 bgp.FlowSpecFragment(
636 operator=0, # Partial match
637 value=bgp.FlowSpecFragment.LF),
639 bgp.FlowSpecFragment(
640 operator=bgp.FlowSpecFragment.MATCH,
641 value=bgp.FlowSpecFragment.FF),
643 bgp.FlowSpecFragment(
644 operator=(bgp.FlowSpecFragment.AND |
645 bgp.FlowSpecFragment.MATCH),
646 value=bgp.FlowSpecFragment.ISF),
648 bgp.FlowSpecFragment(
649 operator=bgp.FlowSpecFragment.NOT,
650 value=bgp.FlowSpecFragment.DF)
652 msg = bgp.FlowSpecVPNv4NLRI.from_user(
653 route_dist='65001:250',
654 dst_prefix='10.0.0.0/24',
655 src_prefix='20.0.0.0/24',
657 port='>=8000 & <=9000 | ==80',
658 dst_port='8080 >9000&<9050 | <=1000',
659 src_port='<=9090 & >=9080 <10100 & >10000',
662 tcp_flags='SYN+ACK & !=URGENT',
663 packet_len='1000 & 1100',
665 fragment='LF ==FF&==ISF | !=DF')
666 msg2 = bgp.FlowSpecVPNv4NLRI(route_dist='65001:250', rules=rules)
667 binmsg = msg.serialize()
668 binmsg2 = msg2.serialize()
669 eq_(str(msg), str(msg2))
670 eq_(binary_str(binmsg), binary_str(binmsg2))
671 msg3, rest = bgp.FlowSpecVPNv4NLRI.parser(binmsg)
672 eq_(str(msg), str(msg3))
675 def test_flowspec_user_interface_ipv6(self):
676 rules = RULES_BASE + [
677 # dst_prefix='2001:2/128/32'
678 bgp.FlowSpecIPv6DestPrefix(
679 addr='2001::2', offset=32, length=128),
680 # src_prefix='3002::3/128'
681 bgp.FlowSpecIPv6SrcPrefix(
682 addr='3002::3', length=128),
684 bgp.FlowSpecNextHeader(
685 operator=bgp.FlowSpecNextHeader.EQ, value=6),
687 bgp.FlowSpecIPv6Fragment(
688 operator=0, # Partial match
689 value=bgp.FlowSpecFragment.LF),
691 bgp.FlowSpecIPv6Fragment(
692 operator=bgp.FlowSpecFragment.MATCH,
693 value=bgp.FlowSpecFragment.FF),
695 bgp.FlowSpecIPv6Fragment(
696 operator=(bgp.FlowSpecFragment.AND |
697 bgp.FlowSpecFragment.MATCH),
698 value=bgp.FlowSpecFragment.ISF),
700 bgp.FlowSpecIPv6Fragment(
701 operator=bgp.FlowSpecFragment.NOT,
702 value=bgp.FlowSpecFragment.LF),
704 bgp.FlowSpecIPv6FlowLabel(
705 operator=bgp.FlowSpecIPv6FlowLabel.EQ,
708 msg = bgp.FlowSpecIPv6NLRI.from_user(
709 dst_prefix='2001::2/128/32',
710 src_prefix='3002::3/128',
712 port='>=8000 & <=9000 | ==80',
713 dst_port='8080 >9000&<9050 | <=1000',
714 src_port='<=9090 & >=9080 <10100 & >10000',
717 tcp_flags='SYN+ACK & !=URGENT',
718 packet_len='1000 & 1100',
720 fragment='LF ==FF&==ISF | !=LF',
723 msg2 = bgp.FlowSpecIPv6NLRI(rules=rules)
724 binmsg = msg.serialize()
725 binmsg2 = msg2.serialize()
726 eq_(str(msg), str(msg2))
727 eq_(binary_str(binmsg), binary_str(binmsg2))
728 msg3, rest = bgp.FlowSpecIPv6NLRI.parser(binmsg)
729 eq_(str(msg), str(msg3))
732 def test_flowspec_user_interface_vpnv6(self):
733 rules = RULES_BASE + [
734 # dst_prefix='2001:2/128/32'
735 bgp.FlowSpecIPv6DestPrefix(
736 addr='2001::2', offset=32, length=128),
737 # src_prefix='3002::3/128'
738 bgp.FlowSpecIPv6SrcPrefix(
739 addr='3002::3', length=128),
741 bgp.FlowSpecNextHeader(
742 operator=bgp.FlowSpecNextHeader.EQ, value=6),
744 bgp.FlowSpecIPv6Fragment(
745 operator=0, # Partial match
746 value=bgp.FlowSpecFragment.LF),
748 bgp.FlowSpecIPv6Fragment(
749 operator=bgp.FlowSpecFragment.MATCH,
750 value=bgp.FlowSpecFragment.FF),
752 bgp.FlowSpecIPv6Fragment(
753 operator=(bgp.FlowSpecFragment.AND |
754 bgp.FlowSpecFragment.MATCH),
755 value=bgp.FlowSpecFragment.ISF),
757 bgp.FlowSpecIPv6Fragment(
758 operator=bgp.FlowSpecFragment.NOT,
759 value=bgp.FlowSpecFragment.LF),
761 bgp.FlowSpecIPv6FlowLabel(
762 operator=bgp.FlowSpecIPv6FlowLabel.EQ,
765 msg = bgp.FlowSpecVPNv6NLRI.from_user(
766 route_dist='65001:250',
767 dst_prefix='2001::2/128/32',
768 src_prefix='3002::3/128',
770 port='>=8000 & <=9000 | ==80',
771 dst_port='8080 >9000&<9050 | <=1000',
772 src_port='<=9090 & >=9080 <10100 & >10000',
775 tcp_flags='SYN+ACK & !=URGENT',
776 packet_len='1000 & 1100',
778 fragment='LF ==FF&==ISF | !=LF',
781 msg2 = bgp.FlowSpecVPNv6NLRI(route_dist='65001:250', rules=rules)
782 binmsg = msg.serialize()
783 binmsg2 = msg2.serialize()
784 eq_(str(msg), str(msg2))
785 eq_(binary_str(binmsg), binary_str(binmsg2))
786 msg3, rest = bgp.FlowSpecVPNv6NLRI.parser(binmsg)
787 eq_(str(msg), str(msg3))
790 def test_flowspec_user_interface_l2vpn(self):
791 rules = RULES_L2VPN_BASE
792 msg = bgp.FlowSpecL2VPNNLRI.from_user(
793 route_dist='65001:250',
795 src_mac='12:34:56:78:90:AB',
796 dst_mac='BE:EF:C0:FF:EE:DD',
803 inner_vlan_id='<3000',
804 inner_vlan_cos='<=5',
806 msg2 = bgp.FlowSpecL2VPNNLRI(route_dist='65001:250', rules=rules)
807 binmsg = msg.serialize()
808 binmsg2 = msg2.serialize()
809 eq_(str(msg), str(msg2))
810 eq_(binary_str(binmsg), binary_str(binmsg2))
811 msg3, rest = bgp.FlowSpecL2VPNNLRI.parser(binmsg)
812 eq_(str(msg), str(msg3))