11/30/2018

Arista EOS, SSO support starts from 4.20.5F

On Sand platform, 7500R/E series. And 4.20.5F was released around Arp 2018. (bl)

We have 2 commands to check if system is sso-ready:
  • wait-for-warmup checks for any agent to be not ready
  • show redundancy stat is to ensure sso stage participating agents to be warm
And better to run these 2 commands on both sup:


bn302.10:49:50#wait-for-warmup
bn302.10:51:11#show redundancy states
  my state = ACTIVE
peer state = STANDBY HOT
      Unit = Primary
   Unit ID = 1

Redundancy Protocol (Operational) = Stateful Switchover
Redundancy Protocol (Configured) = Stateful Switchover
Communications = Up
switchover completion timeout = 120.0 seconds (default)
Not ready for switchover (Agents not ready in standby supervisor)
Agents not ready =
   Sand

  Last switchover time = 10:00:13 ago
Last switchover reason = Supervisor has control of the active supervisor lock
bn302.10:51:16#sess peer-supervisor wait-for-warmup

bn302.10:51:29#sess peer-supervisor show redu stat
  my state = STANDBY HOT
peer state = ACTIVE
      Unit = Secondary
   Unit ID = 2

Redundancy Protocol (Operational) = Stateful Switchover
Redundancy Protocol (Configured) = Stateful Switchover
Communications = Up
switchover completion timeout = 120.0 seconds (default)
Not ready for switchover (Agents not ready in standby supervisor)
Agents not ready =
   Sand

11/29/2018

Arista Linux Essential (2)

Useful Utilities
  • Date/time
    • date +%Y%m%d-%H%M%S
    • Epoch - Linux born time
  • Sort
    • du -s /var/* | sort -n
    • -n: numeric order
  • Cut
    • cut -d: -f:1,6 /etc/password
    • -c: cut columns
  • Diff:
    • Cli -p15 -c "show run" | diff -y -w -B --suppress-common-lines - /mnt/flash/startup-config
    • -B --ingore-blank-lines
    • -y --side-by-side
    • -w --ignore-all-space
  • regexp:
    • greedy vs lazy, ? at the end of pattern
  • grep = global reg exp print
    • -i: ignore case
    • -v: inverse, not-matching
    • -A: print # lines AFTER matching
    • -B: print # lines BEFORE matching
  • sed = powerful stream editor
    • remove quotes: sed -e 's/"//g'
    • reverse ip address:
      • echo "10.20.30.40" | sed -e 's/\([0-9]+\)\.\([0-9]+\)\.\([0-9]+\)\.\([0-9]+\)/\4.\3.\2.\1/'
      • reverse A-record to fwd record
  • awk
    • awk -F: '{print $1, $6}
    • alias shmc show int | awk '/^[A-Z]/ { intf=$1 } 
  • tar
    • tar czvf config.1.gz config.1

[admin@bn303 etc]$ Cli -p15 -c "show run" | diff -y -w -B --suppress-common-lines - /mnt/flash/startup-config
! Command: show running-config        | ! Startup-config last modified at  Wed Nov 28 17:01:44 2018 b
! device: bn303 (DCS-7512N, EOS-4.20.1F)       | ! device: bn303 (DCS-7512N, EOS-4.20.10M)

Arista Linux Essentials (1)

From the course - "Arista Linux Essentials"

Linux Flavors

  • Linux Distribution = Distro
    • Generally includes:
      • Kernel
      • Package manager
      • GNU tools and libraries
      • Documentation
      • GUI
  • Debian
    • All Ubuntu are Debian distro
  • Gentoo
    • For power users
    • ChromeOS is based on Gentoo
  • Android:
    • Uses a Linux Kernel
    • NO GNU tools and libraries, like glibc
  • SUSE
  • Fedora:
    • Red Hat, CentOS
    • Oracle's Unix OS
      • Not Linux anymore because changing kernel 
    • Arista EOS is Fedora Core
      • No change in kernel
      • ver 18 or 21 now
Bootup

  • Boot Loaders:
    • Same on all computers
    • Multi-stage
  • First: BIOS/POST
    • Stored in ROM or NVRAM
    • Initialize system hw
  • MBR (Master Boot Record, Boot Loader) 
    • Not OS-specific
    • Examples: Coreboot, LILO, GRUB
    • @arista switch, Aboot = a mini linux
    • Point to VBR
  • VBR (Volume Boot Record) .... OS Boot .... Kernel
  • OS Boot
    • dmesg display kernel message buffer
Arista Boot:
  • Power On:
    • BIOS
  • Active partition
    • Aboot -> init
    • init -> boot-config
    • ctrl - C to stop Aboot calls kexec
  • EOS Kernel:
    • Aboot calls kexec
EOS Boot Stages
  • EOS Stage 1:
    • /mnt/flash/persist
    • boot hooks - patch, bug fix here
    • not change kernel, change boot
  • Hw Init:
    • FRU initialize
    • Cell type config - module/fixed, supervisor
    • hw device tree
  • EOS Stage 2:
    • Kernel modules
    • ProcMgr
    • SysDB
    • Launcher
Init/runLevel:
  • scripts in /etc/init.d
  • init <runlevel>
Package Management:
  • wget - a web client to download files
    • in aboot
  • curl - more protocol support, http/ftp/imap/scp/....
    • not in aboot
  • Package Managers:
    • different distros use different manager
    • Debian/Ubuntu
      • uses dpkg
      • format is .deb
      • advanced tool apt, manage dependencies
      • apt-get, manage installation
    • Fedors (EOS) 
      • uses rpm
      • format is .rpm
      • yum manage dependencies
      • as Fedora 18, yum is replaced by dnf
  • sudo dnf install sysstat

Python Notes (3) - Beautiful Python Code by Raymond Hettinger

https://www.youtube.com/watch?v=OSGv2VnC0go

Faster and prettier code:

1. Looping backwards
for color in reversed(colors):
    print color

2. Looping over collection and indices
for i, color in enumerate(colors):
    print i, ":", color

3. Zip of 2 lists
for name, color in zip(names, colors):
    print name, ":", color

! zip has higher memory req, prone to cache miss;
! in python 3.x, using izip instead of zip

4. Sorted list
for color in sorted(colors):
for color in sorted(colors, reverse=True):

def compare_length(c1, c2):
    if len(c1) &lt; len(c2): return -1
    if len(c1) &gt; len(c2): return 1
    return 0

for color in sorted(colors, cmp=compare_length):
for color in sorted(colors, key=len):

Looping over a dict with keys and values:
for k,v in d.items():     # req. memory to store list
for k,v in d.iteritems(): # use iterator instead of mem

Counting with dict
d ={}
for color in colors:
    d[color] = d.get(color, 0) + 1

d = defaultdict(int)
for color in colors:
    d[color] += 1

Grouping with dictionaries:
# group the list by length
names = ['Raymond', 'Rachel', 'Matthew', 'Roger', 'Betty']

#old
d = {}
for name in names:
    key = len(name)
    if key not in d:
        d[key] = []
    d[key].append(name)

#1
d = {}
for name in names:
    key = len(name)
    d.setdefault(key, []).append(name)

#2
d = defaultdict(list)
for name in names:
    key = len(name)
    d[key].append(name)

Function calls with keyword arguments
twitter_search('@obama', False, 20, True)

twitter_search('@obama', retweets=False, numtweets=20, 
               popular=True)


Packing/Unpacking = simultaneous state updates
x, y, dx, dy = ( x + dx *t,
                 y + dy *t,
                 influence(m,x,y),
                 influence(m,x,y))

Concatenating strings
', '.join(names)

Updating sequences
names = ['Raymond', 'Rachel', 'Matthew', 'Roger', 'Betty']

del names[0]
names.pop(0)
names.insert(0, 'mark')

#==&gt;
names = deque(['Raymond', 'Rachel', 'Matthew', 'Roger', 'Betty'])

del names[0]
names.popleft()
names.appendleft('mark')

Python Notes (2)

1. Sort: 
  • sorted() vs list.sort()
    • Sorted() returns a new list vs list.sort() does in place. 
    • list.sort() only for list. But sorted() for all iterables. 
  • key function and (reverse=True)
  • Sorted by multiple elements, like by first item then 2nd. 
>>> p = [[1,2,3],[3,2,1],[2,4,6],[1,2,5],[1,3,7],[3,1,0],[1,7,2]]
>>> p.sort(key=lambda x:(x[0], x[2]))
>>> p
[[1, 7, 2], [1, 2, 3], [1, 2, 5], [1, 3, 7], [2, 4, 6], [3, 1, 0], [3, 2, 1]]
  • Sorted by reversed plus asc
>>> p = [[1,2,3],[3,2,1],[2,4,6],[1,2,5],[1,3,7],[13,1,0],[-1,7,2]]
>>> p.sort(key=lambda x:(-x[0], x[2]))
>>> p
[[13, 1, 0], [3, 2, 1], [2, 4, 6], [1, 2, 3], [1, 2, 5], [1, 3, 7], [-1, 7, 2]]


2. SET:

1) No duplicate
2) No order
3) Sets contain only hashable items, for __contain__ method
4) Sets have operator like "-"

_set = set([1,2,3,3]) # (1,2,3)


s1 = set([1,2,3,4])
s2 = set([2,3,5])

l1 = [1,2,3,4]
l2 = [2,3,5]
s1 - s2
set([1, 4])


l1 - l2
Error

3. Variable length arguments in function call

positional argument with unknown number of arguments
def __func__(*args):
    for count, item in enumerate(args):
        print '{0}. {1}'.format(count, thing)

named arguments
def __func__(**kwargs):
    for name, value in kwargs.items():
        print '{0} = {1}' % (name, value)

TCL:
proc __proc__ {first args} {}

4. How to re-import python module in interactive mode
>>> from myrange import *
>>> for i in myrange(1,3,1):
...     print i
...
1 <<<<< extra print out due to debug print
1
2

$ more myrange.py
class myrange:
    def __init__(self, start, end, step):
        self.start = start
        self.end = end
        self.step = step
        print self.step   <<<< need to remove this

Change the py file, and do 2 steps



>>> import myrange   <<< need to import module for reload()
>>> reload(myrange)
<module 'myrange' from 'myrange.py'>
>>> from myrange import *
>>> for i in myrange(1,3,1):
...     print i
...
1  <<<< corrected
2

5. Python class class/instance/internal variables

啥叫class/instance/internal variables? 
- classVar 是Object之间share,一个改,大家都改,也叫Static variable
- instanceVar,所以叫Self.instanceVar,就是object自己本地
- internal,就不说了

class Obj(object):
    classVar = [10,20,30]
    def __init__(self):
        self.instanceVar = [1,2,3]
        internalVar = [100,200,300]

o1 = Obj()
o2 = Obj()

o1.instanceVar.append(11)
o1.instanceVar.append(12)
o2.instanceVar.append(21)
o2.instanceVar.append(22)

print o1.instanceVar
print o2.instanceVar

o1.classVar.append(111)
o2.classVar.append(222)
print o1.classVar
print o2.classVar

Python Notes (1)

1. Python FAQ:
https://docs.python.org/2.7/faq/programming.html

2. Python module search path
https://docs.python.org/2.7/tutorial/modules.html#the-module-search-path

If you do an "import syslib", how does the python locate the library?


1. local directory <<<< surprised?!

2. PYTHONPATH

so if you have a locally mistaken syslib.py or syslib.pyc under the local directory, you gonna break this import. And if you see something wanky, print cmd.__file__ will be helpful (or cmd.__version__)


3. Python Set
https://docs.python.org/3/tutorial/datastructures.html#sets
  • {} and set() can be used to create set
  • But to create an empty one, must use set(), not {} which is to create a dictionary. 
  • set_ = {0}
4. 3 Ways to delete an element in a list
1) most efficient - del List[idx]
2) less efficient if need to have the element - List.pop(idx)
3) lest effificient - slice, List[:i] + List[i+1:]

5. Python reduce, filter
>>> l = [1,2,3,4]
>>> reduce( (lambda x,y: x*10+y), l)
1234
>>> reduce( (lambda x,y: x*100+y), l)
1020304
>>> l = range(1, 100, 5)
>>> l
[1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61, 66, 71, 76, 81, 86, 91, 96]
>>> filter(lambda x:x%4, l)

[1, 6, 11, 21, 26, 31, 41, 46, 51, 61, 66, 71, 81, 86, 91]

6. Python Naming Convention

http://legacy.python.org/dev/peps/pep-0008/#code-lay-out
  • limit all lines to 79,docstring/comment to 72
class Rectangle(Blob):

    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if (width == 0 and height == 0 and
                color == 'red' and emphasis == 'strong' or
                highlight &gt; 100):
            raise ValueError("sorry, you lose")
        if width == 0 and height == 0 and (color == 'red' or
                                           emphasis is None):
            raise ValueError("I don't think so -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)

  • Module: short, 
    • all-lower-case name, like pystock.py
  • Class: CapWords, like 
    • StockHist, StockInfo, StockERHist
  • Function: 
    • lower_case_with_underscore
  • Method and instance: 
    • lower_case_with_underscore
  • Constants: 
    • ALL_CAPITALS_WITH_UNDERSCORE
  • Internal attribute: 
    • _single_leading_underscore
    • NOT imported. 
  • empty sequence = FALSE, so 
    • YES: if not seq:... 
    • NO: if len(seq)
  • Attributes: 
    • self.lower_case_with_underscore



11/16/2018

SR Policy Architecture

https://datatracker.ietf.org/doc/html/draft-filsfils-spring-segment-routing-policy-06.txt

SR Policy包括什么?
  1. ID of SR Policy = <headend, color, endpoint>
  2. 1个Policy可以有多个Candidate Path, 一个CP可以有多个SID-lists, 可以有weight for LB
  3. Protocol origin of CP 
    • 10: PCEP; 
    • 20: BGP SR; 
    • 30: Local, CLI/Yang...
  4. Originator of CP, 160b = 20B
    • = 4B AS# + 16B Addr (128b) 
    • 如果Addr是v4,就放在最后4B
  5. Discriminator of CP, default 0, 这个是啥?一个就是seq#,作为tie-breaker
  6. ID of CP = <protoOrig, originator, discrimator>
  7. pref of CP = 100
  8. Valid of CP, 就是SID是valid
  9. Active CP
    • higher origin id
    • lower originator ip
    • higher discriminator
  10. SR policy还可以有priority,就是有topology change, 先算那个
SR Policy 例子:
  • 1个policy, <headend, color, endpoint>
  • 2个CP,CP1 is active 因为preference 200
  • CP1有两个SID-List, 都installed in HW, 而且ECMP
验证 CP
  • An explicit CP with SID-list = 应该是指静态CP
    • 为空
    • Weight = 0
    • 1st SID不能resolve
    • non-1st SID of type 3~11 into MPLS Label or SRv6 SID? 什么意思
    • 挺多的,还有最后一个不是prefix SID
  • Dynamic CP
Binding SID
  • 非常关键的一个概念
  • = CP,SR的无缝衔接?
  • 可以代表任何的interface, tunnel. 
Steering:
  • 这个是很关键的概念
  • Headend可以steer traffic,以下方式:
    • local BSID
    • Per-dest, 需要BGP
    • Per-flow?
    • PBR
  • 如果SR Policy失效,就fall back to 普通的routing
  • SR Policy可以是Drop
BSID Steering
  • <B, L2, L3> 变成 <S1, S2, S3, L2, L3> 如果S1不是PHP
Per-Dest Steering:
  • 这个一个是最常见的
  • BGP routes <prefix, N, ext-color-C, VPN-Label-V>
  • Valid SR Policy - <endPt = N, color = C> of SID-list <S1, S2, S3> and BSID B
  • 如果都met,NH != N, 而是=SR policy P of BSID B. 
  • 收到prefix pkt, push <S1, S2, S3, V> label
  • 一个BGP update里面可以有多个color, 如果有对应的policy with colors, 最终只有一个FIB,因为higher color prefered