Skip to content

Commit 83d1418

Browse files
judyjosephpull[bot]
authored andcommitted
[macsec]: show macsec: add --profile option, include profile name in show command output (sonic-net#13940)
This PR is to add the following Add a new options "--profile" to the show macsec command, to show all profiles in device Update the currentl show macsec command, to show profile in each interface o/p. This will tell which macsec profile the interface is attached to.
1 parent 8f62a4c commit 83d1418

File tree

3 files changed

+168
-15
lines changed

3 files changed

+168
-15
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
{
2+
"MACSEC_PROFILE|macsec_profile": {
3+
"cipher_suite": "GCM-AES-XPN-256",
4+
"policy": "security",
5+
"primary_cak": "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF",
6+
"primary_ckn": "6162636465666768696A6B6C6D6E6F707172737475767778797A303132333435",
7+
"priority": "0",
8+
"rekey_period": "900",
9+
"send_sci": "true"
10+
},
11+
"PORT|Ethernet0": {
12+
"alias": "Ethernet1/1",
13+
"asic_port_name": "Eth0-ASIC0",
14+
"coreid": "1",
15+
"coreportid": "1",
16+
"description": "Ethernet1/1",
17+
"index": "1",
18+
"lanes": "72,73,74,75,76,77,78,79",
19+
"macsec": "macsec_profile",
20+
"mtu": "9100",
21+
"numvoq": "8",
22+
"pfc_asym": "off",
23+
"role": "Ext",
24+
"speed": "400000",
25+
"tpid": "0x8100"
26+
},
27+
"PORT|Ethernet1": {
28+
"alias": "Ethernet2/1",
29+
"asic_port_name": "Eth0-ASIC0",
30+
"coreid": "1",
31+
"coreportid": "1",
32+
"description": "Ethernet2/1",
33+
"index": "1",
34+
"lanes": "72,73,74,75,76,77,78,79",
35+
"macsec": "macsec_profile",
36+
"mtu": "9100",
37+
"numvoq": "8",
38+
"pfc_asym": "off",
39+
"role": "Ext",
40+
"speed": "400000",
41+
"tpid": "0x8100"
42+
},
43+
"PORT|Ethernet4": {
44+
"alias": "Ethernet5/1",
45+
"asic_port_name": "Eth0-ASIC0",
46+
"coreid": "1",
47+
"coreportid": "1",
48+
"description": "Ethernet5/1",
49+
"index": "1",
50+
"lanes": "72,73,74,75,76,77,78,79",
51+
"macsec": "macsec_profile",
52+
"mtu": "9100",
53+
"numvoq": "8",
54+
"pfc_asym": "off",
55+
"role": "Ext",
56+
"speed": "400000",
57+
"tpid": "0x8100"
58+
},
59+
"PORT|Ethernet5": {
60+
"alias": "Ethernet6/1",
61+
"asic_port_name": "Eth0-ASIC0",
62+
"coreid": "1",
63+
"coreportid": "1",
64+
"description": "Ethernet6/1",
65+
"index": "1",
66+
"lanes": "72,73,74,75,76,77,78,79",
67+
"macsec": "macsec_profile",
68+
"mtu": "9100",
69+
"numvoq": "8",
70+
"pfc_asym": "off",
71+
"role": "Ext",
72+
"speed": "400000",
73+
"tpid": "0x8100"
74+
}
75+
}

dockers/docker-macsec/cli-plugin-tests/test_show_macsec.py

+4
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@ def test_show_one_port(self):
2323
result = runner.invoke(show_macsec.macsec,["Ethernet1"])
2424
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
2525

26+
def test_show_profile(self):
27+
runner = CliRunner()
28+
result = runner.invoke(show_macsec.macsec,["--profile"])
29+
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)

dockers/docker-macsec/cli/show/plugins/show_macsec.py

+89-15
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@
1818
DB_CONNECTOR = None
1919
COUNTER_TABLE = None
2020

21+
class MACsecCfgMeta(object):
22+
def __init__(self, *args) -> None:
23+
SEPARATOR = DB_CONNECTOR.get_db_separator(DB_CONNECTOR.CONFIG_DB)
24+
self.key = self.__class__.get_cfg_table_name() + SEPARATOR + \
25+
SEPARATOR.join(args)
26+
self.cfgMeta = DB_CONNECTOR.get_all(
27+
DB_CONNECTOR.CONFIG_DB, self.key)
28+
if len(self.cfgMeta) == 0:
29+
raise ValueError("No such MACsecCfgMeta: {}".format(self.key))
30+
for k, v in self.cfgMeta.items():
31+
setattr(self, k, v)
2132

2233
class MACsecAppMeta(object):
2334
def __init__(self, *args) -> None:
@@ -126,23 +137,55 @@ def get_header(self):
126137
return "MACsec Egress SC ({})\n".format(self.sci)
127138

128139

129-
class MACsecPort(MACsecAppMeta):
140+
class MACsecPort(MACsecAppMeta, MACsecCfgMeta):
130141
def __init__(self, port_name: str) -> None:
131142
self.port_name = port_name
132-
super(MACsecPort, self).__init__(port_name)
143+
MACsecAppMeta.__init__(self, port_name)
144+
MACsecCfgMeta.__init__(self, port_name)
133145

134146
@classmethod
135147
def get_appl_table_name(cls) -> str:
136148
return "MACSEC_PORT_TABLE"
137149

150+
@classmethod
151+
def get_cfg_table_name(cls) -> str:
152+
return "PORT"
153+
138154
def dump_str(self, cache = None) -> str:
139155
buffer = self.get_header()
156+
157+
# Add the profile information to the meta dict from config meta dict
158+
self.meta["profile"] = self.cfgMeta["macsec"]
159+
140160
buffer += tabulate(sorted(self.meta.items(), key=lambda x: x[0]))
141161
return buffer
142162

143163
def get_header(self) -> str:
144164
return "MACsec port({})\n".format(self.port_name)
145165

166+
class MACsecProfile(MACsecCfgMeta):
167+
def __init__(self, profile_name: str) -> None:
168+
self.profile_name = profile_name
169+
super(MACsecProfile, self).__init__(profile_name)
170+
171+
@classmethod
172+
def get_cfg_table_name(cls) -> str:
173+
return "MACSEC_PROFILE"
174+
175+
def dump_str(self, cache = None) -> str:
176+
buffer = self.get_header()
177+
178+
# Don't display the primary and fallback CAK
179+
if 'primary_cak' in self.cfgMeta: del self.cfgMeta['primary_cak']
180+
if 'fallback_cak' in self.cfgMeta: del self.cfgMeta['fallback_cak']
181+
182+
t_buffer = tabulate(sorted(self.cfgMeta.items(), key=lambda x: x[0]))
183+
t_buffer = "\n".join(["\t" + line for line in t_buffer.splitlines()])
184+
buffer += t_buffer
185+
return buffer
186+
187+
def get_header(self) -> str:
188+
return "MACsec profile : {}\n".format(self.profile_name)
146189

147190
def create_macsec_obj(key: str) -> MACsecAppMeta:
148191
attr = key.split(":")
@@ -161,6 +204,14 @@ def create_macsec_obj(key: str) -> MACsecAppMeta:
161204
except ValueError as e:
162205
return None
163206

207+
def create_macsec_profile_obj(key: str) -> MACsecCfgMeta:
208+
attr = key.split("|")
209+
try:
210+
if attr[0] == MACsecProfile.get_cfg_table_name():
211+
return MACsecProfile(attr[1])
212+
raise TypeError("Unknown MACsec object type")
213+
except ValueError as e:
214+
return None
164215

165216
def create_macsec_objs(interface_name: str) -> typing.List[MACsecAppMeta]:
166217
objs = []
@@ -192,6 +243,12 @@ def create_macsec_objs(interface_name: str) -> typing.List[MACsecAppMeta]:
192243
return objs
193244

194245

246+
def create_macsec_profiles_objs(profile_name: str) -> typing.List[MACsecCfgMeta]:
247+
objs = []
248+
objs.append(create_macsec_profile_obj(MACsecProfile.get_cfg_table_name() + "|" + profile_name))
249+
return objs
250+
251+
195252
def cache_find(cache: dict, target: MACsecAppMeta) -> MACsecAppMeta:
196253
if not cache or not cache["objs"]:
197254
return None
@@ -207,34 +264,51 @@ def cache_find(cache: dict, target: MACsecAppMeta) -> MACsecAppMeta:
207264

208265
@click.command()
209266
@click.argument('interface_name', required=False)
210-
@click.option('--dump-file', is_flag=True, required=False, default=False)
267+
@click.option('--profile', is_flag=True, required=False, default=False, help="show all macsec profiles")
268+
@click.option('--dump-file', is_flag=True, required=False, default=False, help="store show output to a file")
211269
@multi_asic_util.multi_asic_click_options
212-
def macsec(interface_name, dump_file, namespace, display):
213-
MacsecContext(namespace, display).show(interface_name, dump_file)
270+
def macsec(interface_name, dump_file, namespace, display, profile):
271+
if interface_name is not None and profile:
272+
click.echo('Interface name is not valid with profile option')
273+
return
274+
MacsecContext(namespace, display).show(interface_name, dump_file, profile)
214275

215276
class MacsecContext(object):
216277

217278
def __init__(self, namespace_option, display_option):
218279
self.db = None
219280
self.multi_asic = multi_asic_util.MultiAsic(
220281
display_option, namespace_option)
282+
self.macsec_profiles = []
221283

222284
@multi_asic_util.run_on_multi_asic
223-
def show(self, interface_name, dump_file):
285+
def show(self, interface_name, dump_file, profile):
224286
global DB_CONNECTOR
225287
global COUNTER_TABLE
226288
DB_CONNECTOR = self.db
227-
COUNTER_TABLE = CounterTable(self.db.get_redis_client(self.db.COUNTERS_DB))
228289

229-
interface_names = [name.split(":")[1] for name in self.db.keys(self.db.APPL_DB, "MACSEC_PORT*")]
230-
if interface_name is not None:
231-
if interface_name not in interface_names:
232-
return
233-
interface_names = [interface_name]
234-
objs = []
290+
if not profile:
291+
COUNTER_TABLE = CounterTable(self.db.get_redis_client(self.db.COUNTERS_DB))
292+
293+
interface_names = [name.split(":")[1] for name in self.db.keys(self.db.APPL_DB, "MACSEC_PORT*")]
294+
if interface_name is not None:
295+
if interface_name not in interface_names:
296+
return
297+
interface_names = [interface_name]
298+
objs = []
235299

236-
for interface_name in natsorted(interface_names):
237-
objs += create_macsec_objs(interface_name)
300+
for interface_name in natsorted(interface_names):
301+
objs += create_macsec_objs(interface_name)
302+
else:
303+
profile_names = [name.split("|")[1] for name in self.db.keys(self.db.CONFIG_DB, "MACSEC_PROFILE*")]
304+
objs = []
305+
306+
for profile_name in natsorted(profile_names):
307+
# Check if this macsec profile is already added to profile list. This is in case of
308+
# multi-asic devices where all namespaces will have the same macsec profile defined.
309+
if profile_name not in self.macsec_profiles and not dump_file:
310+
self.macsec_profiles.append(profile_name)
311+
objs += create_macsec_profiles_objs(profile_name)
238312

239313
cache = {}
240314
if os.path.isfile(CACHE_FILE.format(self.multi_asic.current_namespace)):

0 commit comments

Comments
 (0)