diff --git a/utils/p4runtime_lib/helper.py b/utils/p4runtime_lib/helper.py index e2dc2f7..8e3e20b 100644 --- a/utils/p4runtime_lib/helper.py +++ b/utils/p4runtime_lib/helper.py @@ -188,3 +188,13 @@ class P4InfoHelper(object): for field_name, value in action_params.iteritems() ]) return table_entry + + def buildMulticastGroupEntry(self, multicast_group_id, replicas): + mc_entry = p4runtime_pb2.PacketReplicationEngineEntry() + mc_entry.multicast_group_entry.multicast_group_id = multicast_group_id + for replica in replicas: + r = p4runtime_pb2.Replica() + r.egress_port = replica['egress_port'] + r.instance = replica['instance'] + mc_entry.multicast_group_entry.replicas.extend([r]) + return mc_entry diff --git a/utils/p4runtime_lib/simple_controller.py b/utils/p4runtime_lib/simple_controller.py index 4f130ba..94a13ab 100755 --- a/utils/p4runtime_lib/simple_controller.py +++ b/utils/p4runtime_lib/simple_controller.py @@ -127,6 +127,14 @@ def program_switch(addr, device_id, sw_conf_file, workdir, proto_dump_fpath): for entry in table_entries: info(tableEntryToString(entry)) insertTableEntry(sw, entry, p4info_helper) + + if 'multicast_group_entries' in sw_conf: + group_entries = sw_conf['multicast_group_entries'] + info("Inserting %d group entries..." % len(group_entries)) + for entry in group_entries: + info(groupEntryToString(entry)) + insertMulticastGroupEntry(sw, entry, p4info_helper) + finally: sw.shutdown() @@ -191,5 +199,16 @@ def tableEntryToString(flow): flow['table'], match_str, flow['action_name'], params) +def groupEntryToString(rule): + group_id = rule["multicast_group_id"] + replicas = ['%d' % replica["egress_port"] for replica in rule['replicas']] + ports_str = ', '.join(replicas) + return 'Group {0} => ({1})'.format(group_id, ports_str) + +def insertMulticastGroupEntry(sw, rule, p4info_helper): + mc_entry = p4info_helper.buildMulticastGroupEntry(rule["multicast_group_id"], rule['replicas']) + sw.WriteMulticastGroupEntry(mc_entry) + + if __name__ == '__main__': main() diff --git a/utils/p4runtime_lib/switch.py b/utils/p4runtime_lib/switch.py index 3f662f2..a7c4f7a 100644 --- a/utils/p4runtime_lib/switch.py +++ b/utils/p4runtime_lib/switch.py @@ -133,6 +133,18 @@ class SwitchConnection(object): yield response + def WriteMulticastGroupEntry(self, mc_entry, dry_run=False): + request = p4runtime_pb2.WriteRequest() + request.device_id = self.device_id + request.election_id.low = 1 + update = request.updates.add() + update.type = p4runtime_pb2.Update.INSERT + update.entity.packet_replication_engine_entry.CopyFrom(mc_entry) + if dry_run: + print "P4Runtime Write:", request + else: + self.client_stub.Write(request) + class GrpcRequestLogger(grpc.UnaryUnaryClientInterceptor, grpc.UnaryStreamClientInterceptor): """Implementation of a gRPC interceptor that logs request to a file"""