| import logging |
| |
| from oftest import config |
| import oftest.base_tests as base_tests |
| import ofp |
| import time |
| from oftest.testutils import * |
| |
| OFDPA_GROUP_TYPE_SHIFT=28 |
| OFDPA_VLAN_ID_SHIFT =16 |
| OFDPA_TUNNEL_ID_SHIFT =16 |
| |
| #VLAN_TABLE_FLAGS |
| VLAN_TABLE_FLAG_ONLY_UNTAG=1 |
| VLAN_TABLE_FLAG_ONLY_TAG =2 |
| VLAN_TABLE_FLAG_ONLY_BOTH =3 |
| |
| def encode_l2_interface_group_id(vlan, id): |
| return id + (vlan << OFDPA_VLAN_ID_SHIFT) |
| |
| def encode_l2_rewrite_group_id(id): |
| return id + (1 << OFDPA_GROUP_TYPE_SHIFT) |
| |
| def encode_l3_unicast_group_id(id): |
| return id + (2 << OFDPA_GROUP_TYPE_SHIFT) |
| |
| def encode_l2_mcast_group_id(vlan, id): |
| return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (3 << OFDPA_GROUP_TYPE_SHIFT) |
| |
| def encode_l2_flood_group_id(vlan, id): |
| return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (4 << OFDPA_GROUP_TYPE_SHIFT) |
| |
| def encode_l3_interface_group_id(id): |
| return id + (5 << OFDPA_GROUP_TYPE_SHIFT) |
| |
| def encode_l3_mcast_group_id(vlan, id): |
| return id + (vlan << OFDPA_VLAN_ID_SHIFT)+(6 << OFDPA_GROUP_TYPE_SHIFT) |
| |
| def encode_l3_ecmp_group_id(id): |
| return id + (7 << OFDPA_GROUP_TYPE_SHIFT) |
| |
| def encode_l2_overlay_flood_group_id(tunnel_id, index): |
| return id + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT) |
| |
| def encode_l2_overlay_mcast_group_id(tunnel_id, index): |
| return id + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+(9 << OFDPA_GROUP_TYPE_SHIFT) |
| |
| def add_l2_interface_grouop(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False): |
| # group table |
| # set up untag groups for each port |
| group_id_list=[] |
| msgs=[] |
| for of_port in ports: |
| # do stuff |
| group_id = encode_l2_interface_group_id(vlan_id, of_port) |
| group_id_list.append(group_id) |
| if is_tagged: |
| actions = [ |
| ofp.action.output(of_port), |
| ] |
| else: |
| actions = [ |
| ofp.action.pop_vlan(), |
| ofp.action.output(of_port), |
| ] |
| |
| buckets = [ |
| ofp.bucket(actions=actions), |
| ] |
| |
| request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT, |
| group_id=group_id, |
| buckets=buckets |
| ) |
| ctrl.message_send(request) |
| msgs.append(request) |
| |
| if send_barrier: |
| do_barrier(ctrl) |
| |
| return group_id_list, msgs |
| |
| def add_one_l2_interface_grouop(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False): |
| # group table |
| # set up untag groups for each port |
| group_id = encode_l2_interface_group_id(vlan_id, port) |
| |
| if is_tagged: |
| actions = [ |
| ofp.action.output(port), |
| ] |
| else: |
| actions = [ |
| ofp.action.pop_vlan(), |
| ofp.action.output(port), |
| ] |
| |
| buckets = [ |
| ofp.bucket(actions=actions), |
| ] |
| |
| request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT, |
| group_id=group_id, |
| buckets=buckets |
| ) |
| ctrl.message_send(request) |
| |
| if send_barrier: |
| do_barrier(ctrl) |
| |
| return group_id, request |
| |
| def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index): |
| buckets=[] |
| for of_port in ports: |
| group_id = encode_l2_interface_group_id(vlanid, of_port) |
| action=[ofp.action.group(group_id)] |
| buckets.append(ofp.bucket(actions=action)) |
| |
| group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index) |
| request = ofp.message.group_add(group_type=ofp.OFPGT_ALL, |
| group_id=group_id, |
| buckets=buckets |
| ) |
| ctrl.message_send(request) |
| return request |
| |
| def add_l2_flood_group(ctrl, ports, vlanid, id): |
| buckets=[] |
| for of_port in ports: |
| group_id = encode_l2_interface_group_id(vlanid, of_port) |
| action=[ofp.action.group(group_id)] |
| buckets.append(ofp.bucket(actions=action)) |
| |
| group_id =encode_l2_flood_group_id(vlanid, id) |
| request = ofp.message.group_add(group_type=ofp.OFPGT_ALL, |
| group_id=group_id, |
| buckets=buckets |
| ) |
| ctrl.message_send(request) |
| return request |
| |
| def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac): |
| group_id = encode_l2_interface_group_id(vlanid, port) |
| |
| action=[] |
| if src_mac is not None: |
| action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac))) |
| |
| if dst_mac is not None: |
| action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac))) |
| |
| action.append(ofp.action.group(group_id)) |
| |
| buckets = [ofp.bucket(actions=action)] |
| |
| group_id =encode_l2_rewrite_group_id(id) |
| request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT, |
| group_id=group_id, |
| buckets=buckets |
| ) |
| ctrl.message_send(request) |
| return request |
| |
| def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac): |
| group_id = encode_l2_interface_group_id(vlanid, port) |
| |
| action=[] |
| if src_mac is not None: |
| action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac))) |
| |
| if dst_mac is not None: |
| action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac))) |
| |
| action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid))) |
| |
| action.append(ofp.action.group(group_id)) |
| |
| buckets = [ofp.bucket(actions=action)] |
| |
| group_id =encode_l3_unicast_group_id(id) |
| request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT, |
| group_id=group_id, |
| buckets=buckets |
| ) |
| ctrl.message_send(request) |
| return request |
| |
| def add_l3_interface_group(ctrl, port, vlanid, id, src_mac): |
| group_id = encode_l2_interface_group_id(vlanid, port) |
| |
| action=[] |
| action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac))) |
| action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid))) |
| action.append(ofp.action.group(group_id)) |
| |
| buckets = [ofp.bucket(actions=action)] |
| |
| group_id =encode_l3_interface_group_id(id) |
| request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT, |
| group_id=group_id, |
| buckets=buckets |
| ) |
| ctrl.message_send(request) |
| return request |
| |
| def add_l3_ecmp_group(ctrl, id, l3_ucast_groups): |
| buckets=[] |
| for group in l3_ucast_groups: |
| buckets.append(ofp.bucket(actions=[ofp.action.group(group)])) |
| |
| group_id =encode_l3_ecmp_group_id(id) |
| request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT, |
| group_id=group_id, |
| buckets=buckets |
| ) |
| ctrl.message_send(request) |
| return request |
| |
| def add_l3_mcast_group(ctrl, vid, mcast_group_id, groups_on_buckets): |
| buckets=[] |
| for group in groups_on_buckets: |
| buckets.append(ofp.bucket(actions=[ofp.action.group(group)])) |
| |
| group_id =encode_l3_mcast_group_id(vid, mcast_group_id) |
| request = ofp.message.group_add(group_type=ofp.OFPGT_ALL, |
| group_id=group_id, |
| buckets=buckets |
| ) |
| ctrl.message_send(request) |
| return request |
| |
| def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False): |
| # table 10: vlan |
| # goto to table 20 |
| msgs=[] |
| for of_port in ports: |
| if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH): |
| match = ofp.match() |
| match.oxm_list.append(ofp.oxm.in_port(of_port)) |
| match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id)) |
| request = ofp.message.flow_add( |
| table_id=10, |
| cookie=42, |
| match=match, |
| instructions=[ |
| ofp.instruction.goto_table(20) |
| ], |
| priority=0) |
| logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port)) |
| ctrl.message_send(request) |
| |
| if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH): |
| match = ofp.match() |
| match.oxm_list.append(ofp.oxm.in_port(of_port)) |
| match.oxm_list.append(ofp.oxm.vlan_vid(0)) |
| request = ofp.message.flow_add( |
| table_id=10, |
| cookie=42, |
| match=match, |
| instructions=[ |
| ofp.instruction.apply_actions( |
| actions=[ |
| ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)) |
| ] |
| ), |
| ofp.instruction.goto_table(20) |
| ], |
| priority=0) |
| logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port)) |
| ctrl.message_send(request) |
| msgs.append(request) |
| |
| if send_barrier: |
| do_barrier(ctrl) |
| |
| return msgs |
| |
| def add_one_vlan_table_flow(ctrl, of_port, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False): |
| # table 10: vlan |
| # goto to table 20 |
| if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH): |
| match = ofp.match() |
| match.oxm_list.append(ofp.oxm.in_port(of_port)) |
| match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id)) |
| request = ofp.message.flow_add( |
| table_id=10, |
| cookie=42, |
| match=match, |
| instructions=[ |
| ofp.instruction.goto_table(20) |
| ], |
| priority=0) |
| logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port)) |
| ctrl.message_send(request) |
| |
| if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH): |
| match = ofp.match() |
| match.oxm_list.append(ofp.oxm.in_port(of_port)) |
| match.oxm_list.append(ofp.oxm.vlan_vid(0)) |
| request = ofp.message.flow_add( |
| table_id=10, |
| cookie=42, |
| match=match, |
| instructions=[ |
| ofp.instruction.apply_actions( |
| actions=[ |
| ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)) |
| ] |
| ), |
| ofp.instruction.goto_table(20) |
| ], |
| priority=0) |
| logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port)) |
| ctrl.message_send(request) |
| |
| if send_barrier: |
| do_barrier(ctrl) |
| |
| return request |
| |
| def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False): |
| match = ofp.match() |
| match.oxm_list.append(ofp.oxm.eth_dst(dst_mac)) |
| match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid)) |
| request = ofp.message.flow_add( |
| table_id=50, |
| cookie=42, |
| match=match, |
| instructions=[ |
| ofp.instruction.write_actions( |
| actions=[ |
| ofp.action.group(group_id)]), |
| ofp.instruction.goto_table(60) |
| ], |
| buffer_id=ofp.OFP_NO_BUFFER, |
| priority=1000) |
| |
| logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac) |
| ctrl.message_send(request) |
| |
| if send_barrier: |
| do_barrier(ctrl) |
| |
| return request |
| |
| def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, send_barrier=False): |
| match = ofp.match() |
| match.oxm_list.append(ofp.oxm.in_port(in_port)) |
| match.oxm_list.append(ofp.oxm.eth_type(eth_type)) |
| match.oxm_list.append(ofp.oxm.eth_dst(dst_mac)) |
| match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid)) |
| |
| if dst_mac[0]&0x01 == 0x01: #macast |
| goto_table=40 |
| else: |
| goto_table=30 |
| |
| request = ofp.message.flow_add( |
| table_id=20, |
| cookie=42, |
| match=match, |
| instructions=[ |
| ofp.instruction.goto_table(goto_table) |
| ], |
| buffer_id=ofp.OFP_NO_BUFFER, |
| priority=1) |
| |
| logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac) |
| ctrl.message_send(request) |
| |
| if send_barrier: |
| do_barrier(ctrl) |
| |
| return request |
| |
| def add_unicast_routing_flow(ctrl, eth_type, dst_ip, action_group_id, send_barrier=False): |
| match = ofp.match() |
| match.oxm_list.append(ofp.oxm.eth_type(eth_type)) |
| match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip)) |
| |
| request = ofp.message.flow_add( |
| table_id=30, |
| cookie=42, |
| match=match, |
| instructions=[ |
| ofp.instruction.write_actions( |
| actions=[ofp.action.group(action_group_id)]), |
| ofp.instruction.goto_table(60) |
| ], |
| buffer_id=ofp.OFP_NO_BUFFER, |
| priority=1) |
| |
| logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip) |
| ctrl.message_send(request) |
| |
| if send_barrier: |
| do_barrier(ctrl) |
| |
| return request |