Saturday, September 02, 2017

Cisco VSS recovery from a failed router

I recently had a client with a Cisco Virtual Switch System (VSS) pair that had one of the devices fail. I'll not go into the details on that, however I will cover how to recover from a failed VSS switch and get the new device operational again.

Background info:
Cisco VSS Link:  Cisco VSS
My history with VSS:  I hated it for years.  It was very common amongst the engineers I worked (at Cisco for 16 years) with to say "Friends don't let friends run VSS".  I purposefully removed it on several occasions when I was under time crunches because of the additional complexity it introduced during setup and troubleshooting.  In the last few years (shortly after it was available on the Cisco 4500 platform) I changed my mind.  Cisco fixed most of the issues and made setup much better, so I'm ok with it now.

VSS takes two L3 switches and combines their control plane into one.  In a basic fashion you use an active supervisor from one switch and fail over to the standby supervisor in a secondary switch.  All ports are operational in both switches regardless of the current operational supervisor.   There are about 1000 caveats and conditions that make everything I just wrote far too simplistic or wrong, but it serves our purposes here.

Implications to losing a switch:
You just lost the config that was specific to that old switch and you will need to recreate it.
1.  VSS Link configuration - This is the config for the specific interfaces to connect between the two devices.  You might still have the config in the old device, by the time I got to this one it was gone.  I suspect it was from a reboot or other tinkering with the config as the client had attempted the repair at least twice.
2.  You need a switch number that matches the operational switch.
3. Y ou need to initialize the new switch back into the pair.

Procedure:
This is actually very easy.  What you will do is boot up the new device and connect to the console port.

1.  Make sure the software versions are the same and the boot config registry is the same on both switches.

2.  Take a look at the running switch and find this information near the top.
switch virtual domain 200
 switch mode virtual
 switch 2

Domain Number:
The domain number "200" needs to match on both devices.

Switch number:
Please notice that the current operational switch is number 2, or the "B" switch in the VSS Pair.  When you create your config for the new switch it will be switch 1.  They must be different numbers so if switch 2 dies, make the replacement switch 2.  You might also find some priority information.  I'll leave that out as it's not important to what we are doing.  Go ahead and configure priority any way you may need.

Make your own config for the new switch.
switch virtual domain 200
 switch mode virtual
 switch 1

3.  Find the port-channel you need to use.  You will find something like this in the old config.  You are looking for the old port-channel number from the switch you are replacing to the switch that is currently running.  In this case, switch A is being replaced.
!
interface Port-channel1
 description 6840A Po1-->6840B Po2 (VSS LINK)
 no ip address
 no platform qos channel-consistency
!
interface Port-channel2
 description 6840B Po2-->6840A Po1 (VSS LINK)
 no ip address
 no platform qos channel-consistency

So, I'm going to need to recreate Port-Channel 1 on the new switch.  We also need to put the switch virtual link command in there.  Let's put that into the config for the new switch.  Our new switch config now looks like this:
switch virtual domain 200
 switch mode virtual
 switch 1
!
interface Port-channel1
 description 6840A Po1-->6840B Po2 (VSS LINK)
 no ip address
 no platform qos channel-consistency
 switch virtual link 1
!

4.  Go find the interfaces that will be the VSS link.  In this case we will have two and there will probably be no configuration in the existing device.  Not to worry, we will just create them.  Please note that we are working on a single switch right now, so there are only two numbers in the interface (slot/port).  When it become a VSS pair it will have the switch number first.  (switch/slot/port).  We also match the channel-group number with the port-channel number from above.
!
interface TenGigabitEthernet1/20
 description 6840A TE1/20-->Po1-->6840B Te1/20
 no switchport
 no ip address
 no shutdown
 channel-group 1 mode on
!
interface TenGigabitEthernet1/30
 description 6840A TE1/30-->Po1-->6840B Te1/30
 no switchport
 no ip address
 no shutdown
 channel-group 1 mode on

5. Make sure the interfaces are up before you try to do the conversion.
Router(config)#do show int ten 1/20
TenGigabitEthernet1/20 is up, line protocol is up (connected)
Router(config)#do show int ten 1/30
TenGigabitEthernet1/30 is up, line protocol is up (connected)

6.  Initiate the conversion of the new switch into the VSS pair.
Router#switch convert mode virtual

This command will convert all interface names
to naming convention "interface-type switch-number/slot/port",
save the running config to startup-config and
reload the switch.

NOTE: Make sure to configure one or more dual-active detection methods
once the conversion is complete and the switches have come up in VSS mode.

Do you want to proceed? [yes/no]: yes
Converting interface names
Building configuration...
[OK]

7. Verify VSS is running once it's done.
6840A#show switch virtual
Switch mode                  : Virtual Switch
Virtual switch domain number : 200
Local switch number          : 2
Local switch operational role: Virtual Switch Active
Peer switch number           : 1
Peer switch operational role : Virtual Switch Standby

8. The config that was pasted into the new switch:
switch virtual domain 200
 switch mode virtual
 switch 1
!
interface Port-channel1
 description 6840A Po1-->6840B Po2 (VSS LINK)
 no ip address
 no platform qos channel-consistency
 switch virtual link 1
!
interface TenGigabitEthernet1/20
 description 6840A TE1/20-->Po1-->6840B Te1/20
 no switchport
 no ip address
 no shutdown
 channel-group 1 mode on
!
interface TenGigabitEthernet1/30
 description 6840A TE1/30-->Po1-->6840B Te1/30
 no switchport
 no ip address
 no shutdown
 channel-group 1 mode on
!
switch convert mode virtual

Relevance:  
This information should be relevant on the following platforms:  6800, 4500, 6500, 6840

Sunday, January 17, 2016

Python and Swift Boolean Algebra

After spending a number of years under heavy travel from work I decided to leave Cisco and work for a local partner that resells primarily Cisco equipment.  This has given me more time at home and thus more time to do the things I enjoy like programming.

I've been doing a lot of Python lately because it maps well to work related project like Cisco ACI.  I've also spent a bit of time learning about Swift and really like how it's fairly easy to switch between the two even with my limited programming capacity.

Anyway, on to the Boolean Algebra.  I have implemented functions of this a few times when checking state for various programs, but didn't know it had a cool name like Boolean Algebra.  While writing some code this morning in checkio.org I came across this as one of the project and thought I would do it in swift also just to see if it was easy to port the logic between the two as well as learn the other operators.

Below you will find two examples, the first in Python and the second in Swift (playground).  I've done them slightly different in how I'm testing the outcome while still trying to keep it very simple.  It's very possible to write these without the if statements by using a dictionary and it probably what you should do if you are going to put this entire thing in real code but I'm not here to tell you how to write code, just give you the answers on calculate Boolean Algebra.

Python:
#!/usr/bin/env python
operations = ("conjunction", "disjunction", "implication", "exclusive", "equivalence")

def booleanArith (operation, x, y):
    if operation == "conjunction":
        return x & y

    if operation == "disjunction":
        return (x or y)
        
    if operation == "implication":
        return (not(x) or y)
            
    if operation == "exclusive":
        return x != y
        
    if operation == "equivalence":
        return x == y

def runThem(x, y):
    for operation in operations:
        result = (booleanArith(operation, x, y))
        print ("{} - {},  {} == {}".format(operation, x, y, result))
    print ("")

# Testing code
x = False
y = False
runThem(x, y)

x = True
y = False
runThem(x, y)

x = False
y = True
runThem(x, y)

x = True
y = True
runThem(x, y)

And then Swift:
//: Playground - noun: a place where people can play

func booleanArith(operation: String, x: Bool, y: Bool) -> Bool {
    if operation == "conjunction" {
    return (x && y)
    }
    
    if operation == "disjunction"{
    return (x || y)
    }
    
    if operation == "implication"{
    return !x || y
    }
    
    if operation == "exclusive"{
    return x != y
    }
    
    if operation == "equivalence"{
    return x == y
    }
    
    return false
}


// Testing code

print (booleanArith("conjunction", x: false, y: false))
print (booleanArith("disjunction", x: false, y: false))
print (booleanArith("implication", x: false, y: false))
print (booleanArith("exclusive",   x: false, y: false))
print (booleanArith("equivalence", x: false, y: false))

print (booleanArith("conjunction", x: true, y: false))
print (booleanArith("disjunction", x: true, y: false))
print (booleanArith("implication", x: true, y: false))
print (booleanArith("exclusive",   x: true, y: false))
print (booleanArith("equivalence", x: true, y: false))


print (booleanArith("conjunction", x: false, y: true))
print (booleanArith("disjunction", x: false, y: true))
print (booleanArith("implication", x: false, y: true))
print (booleanArith("exclusive",   x: false, y: true))
print (booleanArith("equivalence", x: false, y: true))

print (booleanArith("conjunction", x: true, y: true))
print (booleanArith("disjunction", x: true, y: true))
print (booleanArith("implication", x: true, y: true))
print (booleanArith("exclusive", x: true, y: true))
print (booleanArith("equivalence", x: true, y: true))



Monday, December 27, 2010

Update to ATV2 problem - Fixed

After a few more hours of troubleshooting and reading I found there is a feature in DNSMasq that protects you from a DNS Rebind attack.  Unfortunately, the way Netflix works it uses something that looks just like that, so your DNS queries don't work and you get no video.

With most setups you could change the DNS server of your Apple TV (and iPhones, because this happens on them also) to the google address (8.8.8.8).  Of you can look at your router to see what your ISPs DNS server is and use that.

If you are using DD-WRT, you can upgrade (or look, you might already have this feature if you upgraded in the last 2 months) to a version that has "No DNS Rebind" on the services page in the DNSMasq section.  This turns off that security feature.  Below is a picture with it turned off.  Be sure to reboot your router after you make this change.

If you are using DNSMasq on something else, look into a way to turn off DNS Rebind protection.  There are several commands out there for Linux based systems, but I don't have the time to go check them.  You can start at this link that has some of the commands:
http://www.dd-wrt.com/phpBB2/viewtopic.php?p=518676&sid=26f3585e507c4a2acf83f3fb817971a1 



Sunday, December 26, 2010

Apple TV 2 problems

I've been working on the "no netflix videos" for a few days now, and finally tried something new and got it working.  Prior to this I could browse everything, but trying to play would spin the pinwheel, and then go back to the movie description window.  Now everything works great and I can stream movies and TV shows from Netflix.

Here is what I did.
1.  I connected my ATV2 directly to the back of my cable modem.  This worked.
Going with the idea that maybe there is a connection that is being started from Netflix I decided to try normal port forwarding things on the router.
2.  I setup UPNP.  That didn't work.
3.  I setup a DMZ (basically it port forwards all incoming new connections) to the ATV2.  That didn't work either.

My final setup now until Apple/Netflix/Me figure out what's wrong and fix it is the following:
I used an old Ethernet switch, and have the these thigns connected to it:
1.  Cable modem
2.  Linksys E3000 - WAN Port (my main Internet router for my house with lots of stuff behind it)
3.  ATV2 Ethernet port

The big difference in this setup is that the ATV2 has a public Internet address as opposed to a private address.  If you have more than one Internet device in your house, you are probably using private addressing.  Your ATV probably has an address that starts with 192.168.x.x where x any number between 1 and 254.

Wednesday, May 12, 2010

How to know in what row an accessory was clicked - TableView

I was creating a grouped tableview that had detail disclosures on some of the cells that should then open a new view and make some changes. I'm using the following code to figure out what cell the accessory is in.

The key things to remember are the "accessoryButtonTappedForRowWithIndexPath" method, and then using the switch (indexPath.section) for the section and switch (indexPath.row) for the row.

The trick I used was the copy the "switch" information directly from the method I used to build the table in the first place. I took out the logic I used, but left in a comment to help me remember what line was what. example: // Description

Happy coding!

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {

ServerDescriptionView *serverDescriptionView = [[ServerDescriptionView alloc] initWithNibName:@"ServerDescriptionView" bundle:nil];

serverDescriptionView.profile = profile.agencyPolicyName;

ServerActiveServerView *serverActiveServerView = [[ServerActiveServerView alloc] initWithNibName:@"ServerActiveServerView" bundle:nil];

serverActiveServerView.profile = profile.agencyPolicyName;


switch (indexPath.section) {

case 1:

switch (indexPath.row) {

case 0:

// Description

[[self navigationController] pushViewController:serverDescriptionView animated:YES];

[serverDescriptionView release];

break;

case 1:

// Active Server

[[self navigationController] pushViewController:serverActiveServerView animated:YES];

[serverActiveServerView release];


break;

}

break;

case 2:

switch (indexPath.row) {

case 0:

// Server Power

break;

case 1:

// Unbind from the Template

break;

case 2:

// Reset UUID

break;

}

}

}

Tuesday, May 11, 2010

Calling methods in another class file

Now that I have my app doing quite a few things I'm starting to realize that I should have created one central place to put a bunch of functions and then call them from different views. So, I spent some time in google (because I don't have any iPhone programming books, nor do I know how to program object oriented stuff) and found a few different way to do this. Actually, they are just variations of the same thing. I'll show how I'm doing it in my code now.

In the YourFunctions.h file of the new class:

- (void) showAlert:(int)errorNumber;


In the YourFunctions.m file of the new class:

- (void) showAlert:(int)errorNumber {

UIAlertView *error = [[UIAlertView alloc] initWithTitle:[[NSString alloc] initWithFormat:@"Error: %D", errorNumber]

message:[[NSString alloc] initWithFormat:@"This is an error"]

delegate:nil

cancelButtonTitle:@"OK"

otherButtonTitles: nil];

[error show];

[error release];

}


In the YourView.m file you are calling this new method from:

#import "YourFunctions.h"


// As a test I attached a button to this action.

- (IBAction)showAnAlert {

int errorNumber = 22;

YourFunctions *yourFunctions = [[YourFunctions alloc] init];

[yourFunctions showAlert:errorNumber];

}