@@ -498,6 +498,16 @@ def set_interface_naming_mode(mode):
498
498
f .close ()
499
499
click .echo ("Please logout and log back in for changes take effect." )
500
500
501
+ def get_intf_ipv6_link_local_mode (ctx , interface_name , table_name ):
502
+ config_db = ctx .obj ["config_db" ]
503
+ intf = config_db .get_table (table_name )
504
+ if interface_name in intf :
505
+ if 'ipv6_use_link_local_only' in intf [interface_name ]:
506
+ return intf [interface_name ]['ipv6_use_link_local_only' ]
507
+ else :
508
+ return "disable"
509
+ else :
510
+ return ""
501
511
502
512
def _is_neighbor_ipaddress (config_db , ipaddress ):
503
513
"""Returns True if a neighbor has the IP address <ipaddress>, False if not
@@ -3698,7 +3708,7 @@ def remove(ctx, interface_name, ip_addr):
3698
3708
ctx .fail ("Cannot remove the last IP entry of interface {}. A static {} route is still bound to the RIF." .format (interface_name , ip_ver ))
3699
3709
config_db .set_entry (table_name , (interface_name , ip_addr ), None )
3700
3710
interface_dependent = interface_ipaddr_dependent_on_interface (config_db , interface_name )
3701
- if len (interface_dependent ) == 0 and is_interface_bind_to_vrf (config_db , interface_name ) is False :
3711
+ if len (interface_dependent ) == 0 and is_interface_bind_to_vrf (config_db , interface_name ) is False and get_intf_ipv6_link_local_mode ( ctx , interface_name , table_name ) != "enable" :
3702
3712
config_db .set_entry (table_name , interface_name , None )
3703
3713
3704
3714
if multi_asic .is_multi_asic ():
@@ -4133,6 +4143,130 @@ def unbind(ctx, interface_name):
4133
4143
config_db .set_entry (table_name , interface_name , None )
4134
4144
4135
4145
4146
+ #
4147
+ # 'ipv6' subgroup ('config interface ipv6 ...')
4148
+ #
4149
+
4150
+ @interface .group ()
4151
+ @click .pass_context
4152
+ def ipv6 (ctx ):
4153
+ """Enable or Disable IPv6 processing on interface"""
4154
+ pass
4155
+
4156
+ @ipv6 .group ('enable' )
4157
+ def enable ():
4158
+ """Enable IPv6 processing on interface"""
4159
+ pass
4160
+
4161
+ @ipv6 .group ('disable' )
4162
+ def disable ():
4163
+ """Disble IPv6 processing on interface"""
4164
+ pass
4165
+
4166
+ #
4167
+ # 'config interface ipv6 enable use-link-local-only <interface-name>'
4168
+ #
4169
+
4170
+ @enable .command ('use-link-local-only' )
4171
+ @click .pass_context
4172
+ @click .argument ('interface_name' , metavar = '<interface_name>' , required = True )
4173
+ def enable_use_link_local_only (ctx , interface_name ):
4174
+ """Enable IPv6 link local address on interface"""
4175
+ config_db = ConfigDBConnector ()
4176
+ config_db .connect ()
4177
+ ctx .obj = {}
4178
+ ctx .obj ['config_db' ] = config_db
4179
+ db = ctx .obj ["config_db" ]
4180
+
4181
+ if clicommon .get_interface_naming_mode () == "alias" :
4182
+ interface_name = interface_alias_to_name (db , interface_name )
4183
+ if interface_name is None :
4184
+ ctx .fail ("'interface_name' is None!" )
4185
+
4186
+ if interface_name .startswith ("Ethernet" ):
4187
+ interface_type = "INTERFACE"
4188
+ elif interface_name .startswith ("PortChannel" ):
4189
+ interface_type = "PORTCHANNEL_INTERFACE"
4190
+ elif interface_name .startswith ("Vlan" ):
4191
+ interface_type = "VLAN_INTERFACE"
4192
+ else :
4193
+ ctx .fail ("'interface_name' is not valid. Valid names [Ethernet/PortChannel/Vlan]" )
4194
+
4195
+ if (interface_type == "INTERFACE" ) or (interface_type == "PORTCHANNEL_INTERFACE" ):
4196
+ if interface_name_is_valid (db , interface_name ) is False :
4197
+ ctx .fail ("Interface name %s is invalid. Please enter a valid interface name!!" % (interface_name ))
4198
+
4199
+ if (interface_type == "VLAN_INTERFACE" ):
4200
+ if not clicommon .is_valid_vlan_interface (db , interface_name ):
4201
+ ctx .fail ("Interface name %s is invalid. Please enter a valid interface name!!" % (interface_name ))
4202
+
4203
+ portchannel_member_table = db .get_table ('PORTCHANNEL_MEMBER' )
4204
+
4205
+ if interface_is_in_portchannel (portchannel_member_table , interface_name ):
4206
+ ctx .fail ("{} is configured as a member of portchannel. Cannot configure the IPv6 link local mode!"
4207
+ .format (interface_name ))
4208
+
4209
+ vlan_member_table = db .get_table ('VLAN_MEMBER' )
4210
+
4211
+ if interface_is_in_vlan (vlan_member_table , interface_name ):
4212
+ ctx .fail ("{} is configured as a member of vlan. Cannot configure the IPv6 link local mode!"
4213
+ .format (interface_name ))
4214
+
4215
+ interface_dict = db .get_table (interface_type )
4216
+ set_ipv6_link_local_only_on_interface (db , interface_dict , interface_type , interface_name , "enable" )
4217
+
4218
+ #
4219
+ # 'config interface ipv6 disable use-link-local-only <interface-name>'
4220
+ #
4221
+
4222
+ @disable .command ('use-link-local-only' )
4223
+ @click .pass_context
4224
+ @click .argument ('interface_name' , metavar = '<interface_name>' , required = True )
4225
+ def disable_use_link_local_only (ctx , interface_name ):
4226
+ """Disable IPv6 link local address on interface"""
4227
+ config_db = ConfigDBConnector ()
4228
+ config_db .connect ()
4229
+ ctx .obj = {}
4230
+ ctx .obj ['config_db' ] = config_db
4231
+ db = ctx .obj ["config_db" ]
4232
+
4233
+ if clicommon .get_interface_naming_mode () == "alias" :
4234
+ interface_name = interface_alias_to_name (db , interface_name )
4235
+ if interface_name is None :
4236
+ ctx .fail ("'interface_name' is None!" )
4237
+
4238
+ interface_type = ""
4239
+ if interface_name .startswith ("Ethernet" ):
4240
+ interface_type = "INTERFACE"
4241
+ elif interface_name .startswith ("PortChannel" ):
4242
+ interface_type = "PORTCHANNEL_INTERFACE"
4243
+ elif interface_name .startswith ("Vlan" ):
4244
+ interface_type = "VLAN_INTERFACE"
4245
+ else :
4246
+ ctx .fail ("'interface_name' is not valid. Valid names [Ethernet/PortChannel/Vlan]" )
4247
+
4248
+ if (interface_type == "INTERFACE" ) or (interface_type == "PORTCHANNEL_INTERFACE" ):
4249
+ if interface_name_is_valid (db , interface_name ) is False :
4250
+ ctx .fail ("Interface name %s is invalid. Please enter a valid interface name!!" % (interface_name ))
4251
+
4252
+ if (interface_type == "VLAN_INTERFACE" ):
4253
+ if not clicommon .is_valid_vlan_interface (db , interface_name ):
4254
+ ctx .fail ("Interface name %s is invalid. Please enter a valid interface name!!" % (interface_name ))
4255
+
4256
+ portchannel_member_table = db .get_table ('PORTCHANNEL_MEMBER' )
4257
+
4258
+ if interface_is_in_portchannel (portchannel_member_table , interface_name ):
4259
+ ctx .fail ("{} is configured as a member of portchannel. Cannot configure the IPv6 link local mode!"
4260
+ .format (interface_name ))
4261
+
4262
+ vlan_member_table = db .get_table ('VLAN_MEMBER' )
4263
+ if interface_is_in_vlan (vlan_member_table , interface_name ):
4264
+ ctx .fail ("{} is configured as a member of vlan. Cannot configure the IPv6 link local mode!"
4265
+ .format (interface_name ))
4266
+
4267
+ interface_dict = db .get_table (interface_type )
4268
+ set_ipv6_link_local_only_on_interface (db , interface_dict , interface_type , interface_name , "disable" )
4269
+
4136
4270
#
4137
4271
# 'vrf' group ('config vrf ...')
4138
4272
#
@@ -5554,6 +5688,123 @@ def delete(ctx):
5554
5688
sflow_tbl ['global' ].pop ('agent_id' )
5555
5689
config_db .set_entry ('SFLOW' , 'global' , sflow_tbl ['global' ])
5556
5690
5691
+ #
5692
+ # set ipv6 link local mode on a given interface
5693
+ #
5694
+ def set_ipv6_link_local_only_on_interface (config_db , interface_dict , interface_type , interface_name , mode ):
5695
+
5696
+ curr_mode = config_db .get_entry (interface_type , interface_name ).get ('ipv6_use_link_local_only' )
5697
+ if curr_mode is not None :
5698
+ if curr_mode == mode :
5699
+ return
5700
+ else :
5701
+ if mode == "disable" :
5702
+ return
5703
+
5704
+ if mode == "enable" :
5705
+ config_db .mod_entry (interface_type , interface_name , {"ipv6_use_link_local_only" : mode })
5706
+ return
5707
+
5708
+ # If we are disabling the ipv6 link local on an interface, and if no other interface
5709
+ # attributes/ip addresses are configured on the interface, delete the interface from the interface table
5710
+ exists = False
5711
+ for key in interface_dict .keys ():
5712
+ if not isinstance (key , tuple ):
5713
+ if interface_name == key :
5714
+ #Interface bound to non-default-vrf do not delete the entry
5715
+ if 'vrf_name' in interface_dict [key ]:
5716
+ if len (interface_dict [key ]['vrf_name' ]) > 0 :
5717
+ exists = True
5718
+ break
5719
+ continue
5720
+ if interface_name in key :
5721
+ exists = True
5722
+ break
5723
+
5724
+ if exists :
5725
+ config_db .mod_entry (interface_type , interface_name , {"ipv6_use_link_local_only" : mode })
5726
+ else :
5727
+ config_db .set_entry (interface_type , interface_name , None )
5728
+
5729
+ #
5730
+ # 'ipv6' group ('config ipv6 ...')
5731
+ #
5732
+
5733
+ @config .group ()
5734
+ @click .pass_context
5735
+ def ipv6 (ctx ):
5736
+ """IPv6 configuration"""
5737
+
5738
+ #
5739
+ # 'enable' command ('config ipv6 enable ...')
5740
+ #
5741
+ @ipv6 .group ()
5742
+ @click .pass_context
5743
+ def enable (ctx ):
5744
+ """Enable IPv6 on all interfaces """
5745
+
5746
+ #
5747
+ # 'link-local' command ('config ipv6 enable link-local')
5748
+ #
5749
+ @enable .command ('link-local' )
5750
+ @click .pass_context
5751
+ def enable_link_local (ctx ):
5752
+ """Enable IPv6 link-local on all interfaces """
5753
+ config_db = ConfigDBConnector ()
5754
+ config_db .connect ()
5755
+ vlan_member_table = config_db .get_table ('VLAN_MEMBER' )
5756
+ portchannel_member_table = config_db .get_table ('PORTCHANNEL_MEMBER' )
5757
+
5758
+ mode = "enable"
5759
+
5760
+ # Enable ipv6 link local on VLANs
5761
+ vlan_dict = config_db .get_table ('VLAN' )
5762
+ for key in vlan_dict .keys ():
5763
+ set_ipv6_link_local_only_on_interface (config_db , vlan_dict , 'VLAN_INTERFACE' , key , mode )
5764
+
5765
+ # Enable ipv6 link local on PortChannels
5766
+ portchannel_dict = config_db .get_table ('PORTCHANNEL' )
5767
+ for key in portchannel_dict .keys ():
5768
+ if interface_is_in_vlan (vlan_member_table , key ):
5769
+ continue
5770
+ set_ipv6_link_local_only_on_interface (config_db , portchannel_dict , 'PORTCHANNEL_INTERFACE' , key , mode )
5771
+
5772
+ port_dict = config_db .get_table ('PORT' )
5773
+ for key in port_dict .keys ():
5774
+ if interface_is_in_portchannel (portchannel_member_table , key ) or interface_is_in_vlan (vlan_member_table , key ):
5775
+ continue
5776
+ set_ipv6_link_local_only_on_interface (config_db , port_dict , 'INTERFACE' , key , mode )
5777
+
5778
+ #
5779
+ # 'disable' command ('config ipv6 disable ...')
5780
+ #
5781
+ @ipv6 .group ()
5782
+ @click .pass_context
5783
+ def disable (ctx ):
5784
+ """Disable IPv6 on all interfaces """
5785
+
5786
+ #
5787
+ # 'link-local' command ('config ipv6 disable link-local')
5788
+ #
5789
+ @disable .command ('link-local' )
5790
+ @click .pass_context
5791
+ def disable_link_local (ctx ):
5792
+ """Disable IPv6 link local on all interfaces """
5793
+ config_db = ConfigDBConnector ()
5794
+ config_db .connect ()
5795
+
5796
+ mode = "disable"
5797
+
5798
+ tables = ['INTERFACE' , 'VLAN_INTERFACE' , 'PORTCHANNEL_INTERFACE' ]
5799
+
5800
+ for table_type in tables :
5801
+ table_dict = config_db .get_table (table_type )
5802
+ if table_dict :
5803
+ for key in table_dict .keys ():
5804
+ if isinstance (key , str ) is False :
5805
+ continue
5806
+ set_ipv6_link_local_only_on_interface (config_db , table_dict , table_type , key , mode )
5807
+
5557
5808
5558
5809
# Load plugins and register them
5559
5810
helper = util_base .UtilHelper ()
0 commit comments