Skip to content

Instantly share code, notes, and snippets.

@StephenKing
Last active January 23, 2017 09:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save StephenKing/6f4cea1e0129bcd013a6 to your computer and use it in GitHub Desktop.
Save StephenKing/6f4cea1e0129bcd013a6 to your computer and use it in GitHub Desktop.
Pushing MPLS FlowMods to NEC PF5240
NEC PF5240
# show version
Date 2015/07/02 11:26:13 UTC
Model: PF5240F-48T4XW
S/W: OS-F3PA Ver. V6.0.0.0
H/W: Main board
PF5240F-48T4XW-AX [Y1752CFA0000S4068DCR002:80C50021:2200:11B636-11B636]
Ryu:
master branch from https://github.com/osrg/ryu/tree/0e4fec9f1f86cc2e61f7ae9f4c2597b945eaeec4 (2015/06/30)
from ryu.base import app_manager
from ryu.controller import dpset
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.ofproto import ether
from ryu.lib.packet import packet, ethernet
from time import sleep
class MPLS(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
NEC_TABLE_NORMAL1 = 0
NEC_TABLE_EXPANDED = 1
NEC_TABLE_NORMAL2 = 20
NEC_TABLE_MPLS1 = 50
NEC_TABLE_MPLS2 = 51
NEC_TABLE_SOFTWARE = 99
OVS_TABLE_MPLS1 = 0
OVS_TABLE_MPLS2 = 1
def __init__(self, *args, **kwargs):
super(MPLS, self).__init__(*args, **kwargs)
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self, ev):
datapath = ev.msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
inst = [parser.OFPInstructionActions(
ofproto.OFPIT_APPLY_ACTIONS,
[
parser.OFPActionOutput(
ofproto.OFPP_CONTROLLER,
ofproto.OFPCML_NO_BUFFER)
])]
mod = parser.OFPFlowMod(
datapath=datapath,
priority=0,
match=parser.OFPMatch(),
instructions=inst
)
datapath.send_msg(mod)
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def _packet_in_handler(self, ev):
# If you hit this you might want to increase
# the "miss_send_length" of your switch
if ev.msg.msg_len < ev.msg.total_len:
self.logger.debug("packet truncated: only %s of %s bytes",
ev.msg.msg_len, ev.msg.total_len)
msg = ev.msg
datapath = msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
in_port = msg.match['in_port']
pkt = packet.Packet(msg.data)
eth = pkt.get_protocols(ethernet.ethernet)[0]
self.logger.info("packet in dpid:%s port:%s table:%s %s->%s -- %s", datapath.id, in_port, msg.table_id, eth.src, eth.dst, pkt)
@set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER)
def handler_datapath(self, ev):
if ev.enter:
sleep(1)
if ev.dp.id == 0x000158c232e8b2be:
self.logger.info("Connection by NEC PF5240")
self._nec_pf5240_connect(ev)
elif ev.dp.id == 0x5e3e2c600c457a2f:
self.logger.info("Connection by Quanta")
# self._quanta_connect(ev)
else:
self.logger.warn("Connection by unknown dpid %s", ev.dp.id)
def _nec_pf5240_connect(self, ev):
log_prefix = "pf5240"
datapath = ev.dp
parser = datapath.ofproto_parser
self._empty_table(datapath, self.NEC_TABLE_MPLS1)
self.logger.warn("%s --- start pushing flowmod to table mpls1", log_prefix)
# MPLS1 (this one works)
mod_mpls1 = parser.OFPFlowMod(datapath=datapath,
priority=65000,
match=parser.OFPMatch(
eth_dst='00:30:96:e6:fc:39',
eth_type=ether.ETH_TYPE_MPLS,
),
table_id=self.NEC_TABLE_MPLS1,
instructions=[parser.OFPInstructionGotoTable(self.NEC_TABLE_MPLS2)],
)
datapath.send_msg(mod_mpls1)
sleep(0.5)
self.logger.warn("%s --- done pushing flowmod to table mpls1", log_prefix)
# MPLS2 (this one DOES NOT work)
self._empty_table(datapath, self.NEC_TABLE_MPLS2)
self.logger.warn("%s --- start pushing flowmod to table mpls2", log_prefix)
mod_mpls2 = parser.OFPFlowMod(datapath=datapath,
priority=1000,
match=parser.OFPMatch(
in_port=1,
eth_type=ether.ETH_TYPE_MPLS,
mpls_label=29,
mpls_bos=1),
table_id=self.NEC_TABLE_MPLS2,
instructions=[
parser.OFPInstructionActions(datapath.ofproto.OFPIT_APPLY_ACTIONS,
[
parser.OFPActionPopMpls(ether.ETH_TYPE_IP),
parser.OFPActionDecNwTtl(),
]),
parser.OFPInstructionWriteMetadata(0xc00000a0, 0xffffffff),
parser.OFPInstructionGotoTable(self.NEC_TABLE_NORMAL1)
],
)
datapath.send_msg(mod_mpls2)
sleep(0.5)
self.logger.warn("%s --- done pushing flowmod to table mpls2", log_prefix)
# normal1
self._empty_table(datapath, self.NEC_TABLE_NORMAL1)
self.logger.warn("%s --- start pushing flowmod to table normal1", log_prefix)
mod_normal1 = parser.OFPFlowMod(datapath=datapath,
priority=1,
table_id=self.NEC_TABLE_NORMAL1,
instructions=[
parser.OFPInstructionActions(
datapath.ofproto.OFPIT_APPLY_ACTIONS,
[parser.OFPActionOutput(2)]
),
],
)
# datapath.send_msg(mod_normal1)
sleep(0.5)
self.logger.warn("%s --- done pushing flowmod to table normal1", log_prefix)
def _empty_table(self, datapath, table_id):
self.logger.warn(" --- deleting flow entries in table %s", table_id)
datapath.send_msg(
datapath.ofproto_parser.OFPFlowMod(
datapath,
0,
0,
table_id,
datapath.ofproto.OFPFC_DELETE,
0,
0,
1,
datapath.ofproto.OFPCML_NO_BUFFER,
datapath.ofproto.OFPP_ANY,
datapath.ofproto.OFPG_ANY,
0,
datapath.ofproto_parser.OFPMatch(),
[]
)
)
# show openflow controller-session detail
14:46:57.642667 OFS( 1) RECV 132.187.247.61(6633) : FLOW_MOD
[ver=0x04, type=14, len=80, xid=0x33a4b2fa]
cookie=0x0000000000000000 / 0x0000000000000000
table_id=0x00 [NORMAL1]
command=0x00 [ADD]
idle_timeout=0
hard_timeout=0
priority=0
buffer_id=0xffffffff [NO_BUFFER]
out_port=0x00000000 [unknown]
out_group=0x00000000 (0)
flags=0x0000 [-]
match:
type=0x0001 [OXM]
length=4
instruction[0]:
type=0x0004 [APPLY_ACTIONS]
len=24
action[0]:
type=0x0000 [OUTPUT]
len=16
port=0xfffffffd [CONTROLLER]
max_len=65535 [NO_BUFFER]
14:46:58.728898 OFS( 1) RECV 132.187.247.61(6633) : FLOW_MOD
[ver=0x04, type=14, len=56, xid=0x33a4b2fb]
cookie=0x0000000000000000 / 0x0000000000000000
table_id=0x32 [MPLS1]
command=0x03 [DELETE]
idle_timeout=0
hard_timeout=0
priority=1
buffer_id=0x0000ffff
out_port=0xffffffff [ANY]
out_group=0xffffffff (4294967295) [ANY]
flags=0x0000 [-]
match:
type=0x0001 [OXM]
length=4
14:46:58.735418 OFS( 1) RECV 132.187.247.61(6633) : FLOW_MOD
[ver=0x04, type=14, len=80, xid=0x33a4b2fc]
cookie=0x0000000000000000 / 0x0000000000000000
table_id=0x32 [MPLS1]
command=0x00 [ADD]
idle_timeout=0
hard_timeout=0
priority=65000
buffer_id=0xffffffff [NO_BUFFER]
out_port=0x00000000 [unknown]
out_group=0x00000000 (0)
flags=0x0000 [-]
match:
type=0x0001 [OXM]
length=20
oxm_fields[0]:
oxm_header=0x80000606 [OFB_ETH_DST]
value=0030.96e6.fc39
oxm_fields[1]:
oxm_header=0x80000a02 [OFB_ETH_TYPE]
value=0x8847 [MPLS_UC]
instruction[0]:
type=0x0001 [GOTO_TABLE]
len=8
table_id=0x33 [MPLS2]
14:46:59.231174 OFS( 1) RECV 132.187.247.61(6633) : FLOW_MOD
[ver=0x04, type=14, len=56, xid=0x33a4b2fd]
cookie=0x0000000000000000 / 0x0000000000000000
table_id=0x33 [MPLS2]
command=0x03 [DELETE]
idle_timeout=0
hard_timeout=0
priority=1
buffer_id=0x0000ffff
out_port=0xffffffff [ANY]
out_group=0xffffffff (4294967295) [ANY]
flags=0x0000 [-]
match:
type=0x0001 [OXM]
length=4
14:46:59.233271 OFS( 1) RECV 132.187.247.61(6633) : FLOW_MOD
[ver=0x04, type=14, len=136, xid=0x33a4b2fe]
cookie=0x0000000000000000 / 0x0000000000000000
table_id=0x33 [MPLS2]
command=0x00 [ADD]
idle_timeout=0
hard_timeout=0
priority=1000
buffer_id=0xffffffff [NO_BUFFER]
out_port=0x00000000 [unknown]
out_group=0x00000000 (0)
flags=0x0000 [-]
match:
type=0x0001 [OXM]
length=31
oxm_fields[0]:
oxm_header=0x80000004 [OFB_IN_PORT]
value=0x00000001 [0/01]
oxm_fields[1]:
oxm_header=0x80000a02 [OFB_ETH_TYPE]
value=0x8847 [MPLS_UC]
oxm_fields[2]:
oxm_header=0x80004404 [OFB_MPLS_LABEL]
value=0x0001d
oxm_fields[3]:
oxm_header=0x80004801 [OFB_MPLS_BOS]
value=0x1
instruction[0]:
type=0x0004 [APPLY_ACTIONS]
len=24
action[0]:
type=0x0014 [POP_MPLS]
len=8
ethertype=0x0800 [IPV4]
action[1]:
type=0x0018 [DEC_NW_TTL]
len=8
instruction[1]:
type=0x0002 [WRITE_METADATA]
len=24
metadata=0x00000000c00000a0
metadata_mask=0x00000000ffffffff
instruction[2]:
type=0x0001 [GOTO_TABLE]
len=8
table_id=0x00 [NORMAL1]
14:46:59.736331 OFS( 1) RECV 132.187.247.61(6633) : FLOW_MOD
[ver=0x04, type=14, len=56, xid=0x33a4b2ff]
cookie=0x0000000000000000 / 0x0000000000000000
table_id=0x00 [NORMAL1]
command=0x03 [DELETE]
idle_timeout=0
hard_timeout=0
priority=1
buffer_id=0x0000ffff
out_port=0xffffffff [ANY]
out_group=0xffffffff (4294967295) [ANY]
flags=0x0000 [-]
match:
type=0x0001 [OXM]
length=4
# show running-config
#Last modified by nec at Thu Jul 2 11:17:56 2015 with version V6.0.0.0
!
hostname "pf5240"
clock timezone UTC +1
!
flow detection mode openflow-2
!
ip name-server 132.187.0.13
!
vlan 1
name "VLAN0001"
!
vlan 2
!
spanning-tree mode pvst
!
interface mgmt 0
ip address 172.16.45.9 255.255.255.0
!
interface gigabitethernet 0/1
switchport mode access
!
...
interface tengigabitethernet 0/52
switchport mode access
!
interface vlan 1
!
ip route 0.0.0.0 0.0.0.0 172.16.45.1
!
qos-queue-list list1 wfq min-rate1 600M min-rate2 300M
qos-queue-list list2 wfq min-rate1 700M min-rate2 300M
qos-queue-list list3 wfq min-rate1 500M min-rate2 300M
qos-queue-list list4 wfq min-rate1 500M min-rate2 500M
qos-queue-list list5 wfq min-rate1 400M min-rate2 600M
qos-queue-list list6 wfq min-rate1 600M min-rate2 400M
qos-queue-list list7 wfq min-rate1 700M min-rate2 300M
qos-queue-list list8 wfq min-rate1 1M min-rate2 1M min-rate3 99M
!
ip qos-flow-list l
1 qos udp host 10.0.0.1 host 10.0.0.3 action max-rate 300M
2 qos udp host 10.0.0.2 host 10.0.0.3 action max-rate 75M
3 qos udp any host 10.0.0.3 action max-rate 400M
!
ip qos-flow-list l2
1 qos udp host 10.0.0.1 host 10.0.0.3 action max-rate 300M
3 qos udp any host 10.0.0.3 action max-rate 550M
!
ip qos-flow-list q1
1 qos udp any any action max-rate 640M
!
ip qos-flow-list q2
2 qos udp any any action max-rate 800M
!
line vty 0 2
!
ip ssh
!
openflow-table-resource mode 1
!
openflow openflow-id 1
protocol-version 04
controller controller-name palladionsteffen 1 132.187.12.145 port 6633
echo-request interval 0
openflow-interface gigabitethernet 0/1-48
enable
!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment