Variable
NAME="John"
echo $NAME
echo "$NAME"
echo "${NAME}
Condition
if [[ -z "$string" ]]; then
  echo "String is empty"
elif [[ -n "$string" ]]; then
  echo "String is not empty"
fi
Filter
# Filter comment and empty lines from a file
grep -v '^$\|^\s*\#' temp

# Filter certs
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}’ cacerts.pem
WSS
# Verify endpoint is using secure web sockets
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: ikotak.com" -H "Origin: https://ikotak.com" https://ikotak.com -k
Convert pfx file to pem file
# Conversion to a combined PEM file
openssl pkcs12 -in filename.pfx -out cert.pem -nodes

# Extract the private key form a PFX to a PEM file
openssl pkcs12 -in filename.pfx -nocerts -out key.pem

# Export the certificate only
openssl pkcs12 -in filename.pfx -clcerts -nokeys -out cert.pem

# Remove the password from the extracted private key
openssl rsa -in key.pem -out server.key
Latency Troubleshooting
curl -kso /dev/null https://www.ikotak.com -w "==============\n\n 
| dnslookup: %{time_namelookup}\n 
| connect: %{time_connect}\n 
| appconnect: %{time_appconnect}\n 
| pretransfer: %{time_pretransfer}\n 
| starttransfer: %{time_starttransfer}\n 
| total: %{time_total}\n 
| size: %{size_download}\n 
| HTTPCode=%{http_code}\n\n" ; 

time for i in {1..50}; do curl -s https://ikotak.com > /dev/null; done
Network Emulator
# Add a fixed amount of delay to all packets going out of the local Ethernet
tc qdisc add dev bond0 root netem delay 100ms

# Delete delay
tc qdisc list
tc qdisc del dev bond0 root netem

# Add delay to be 100ms ± 10ms with the next random element depending 25% on the last one
tc qdisc change dev eth0 root netem delay 100ms 10ms 25%

# Packet loss
tc qdisc change dev eth0 root netem loss 0.1%

# Causes the random number generator to be less random and can be used to emulate packet burst losses.
tc qdisc change dev eth0 root netem loss 0.3% 25%

# Packet duplication
 tc qdisc change dev eth0 root netem duplicate 1%

# Packet corruption
tc qdisc change dev eth0 root netem corrupt 0.1%

# Packet re-ordering, 25% of packets (with a correlation of 50%) will get sent immediately, others will be delayed by 10ms.
tc qdisc change dev eth0 root netem delay 10ms reorder 25% 50%
PostgreSQL
sudo -u postgres psql
postgres=# create database mydb;
postgres=# create user myuser with encrypted password ‘mypass’;
postgres=# grant all privileges on database mydb to myuser;

# Quit psql
\q

# Choose database
Sql
\l
\c database_name

# List tables
\dt+

SELECT *
FROM pg_catalog.pg_tables
WHERE schemaname != 'pg_catalog’ AND 
    schemaname != ‘information_schema’;

SELECT * FROM pg_catalog.pg_tables;

# Drop sessions
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = ‘TARGET_DB';
Fiber Channel
# Troubleshooting Fiber Channel connections
$ multipath -ll
mpatha (000219fb) dm-0 PURE,FlashArray
size=500G features='0' hwhandler='1 alua' wp=rw
`-+- policy='service-time 0' prio=50 status=active
  |- 14:0:0:1 sdb 8:16  active ready running
  |- 14:0:1:1 sdd 8:48  active ready running
  |- 12:0:0:1 sdf 8:80  active ready running
  `- 12:0:1:1 sdh 8:112 active ready running
mpathb (000219fc) dm-1 PURE,FlashArray
size=250G features='0' hwhandler='1 alua' wp=rw
`-+- policy='service-time 0' prio=50 status=active
  |- 14:0:0:2 sdc 8:32  active ready running
  |- 14:0:1:2 sde 8:64  active ready running
  |- 12:0:0:2 sdg 8:96  active ready running
  `- 12:0:1:2 sdi 8:128 active ready running 

$ grep -v "zZzZ" -H /sys/class/fc_host/host*/port_state
/sys/class/fc_host/host12/port_state:Linkdown
/sys/class/fc_host/host13/port_state:Linkdown
/sys/class/fc_host/host14/port_state:Online
/sys/class/fc_host/host15/port_state:Linkdown 

$ ll /sys/class/fc_host/
total 0
lrwxrwxrwx. 1 root root 0 Aug 2 17:35 host12 -> ../../devices/pci0000:20/0000:20:03.1/0000:21:00.0/host12/fc_host/host12
lrwxrwxrwx. 1 root root 0 Aug 2 17:35 host13 -> ../../devices/pci0000:20/0000:20:03.1/0000:21:00.1/host13/fc_host/host13
lrwxrwxrwx. 1 root root 0 Aug 2 17:35 host14 -> ../../devices/pci0000:80/0000:80:01.1/0000:81:00.0/host14/fc_host/host14
lrwxrwxrwx. 1 root root 0 Aug 2 17:35 host15 -> ../../devices/pci0000:80/0000:80:01.1/0000:81:00.1/host15/fc_host/host15 

$ cat /sys/class/fc_host/host*/port_name
0x100000620b416b60
0x100000620b416b61
0x100000620b416b75
0x100000620b416b76
PCIe devices
# Get Vendor ID and Device ID of all PCI Devices
grep PCI_ID /sys/bus/pci/devices/*/uevent

# vGPU mdev devices
ls /sys/class/mdev_bus/*/mdev_supported_types
Mellanox NIC
# Upgrade firmware on NIC
/mlxup -u -y -i fw-ConnectX5-rel-16_25_4518-MCX516A-CCA_Ax-UEFI-14.18.19-FlexBoot-3.5.701.bin

# Upgrade using mstflint utility
mstflint -d <lspci-device-id> -i <image-file> b

# Query SRIOV VFs
yum install -y mstflint
for adapter in $(lspci -D| grep -i mel |awk '{print $1}');do
    mstconfig -d ${adapter} query |egrep -i "sriov|vfs”
done

# Set mellanox adapters enable SRIOV set #vfs
for adapter in $(lspci -D| grep -i mel |awk '{print $1}');do
    mstconfig -y -d ${adapter} set SRIOV_EN=1
    mstconfig -y -d ${adapter} set NUM_OF_VFS=64
done

# eSwitch
$ devlink dev eswitch show pci/0000:88:00.0
pci/0000:88:00.0: mode legacy inline-mode none encap enable
Manual sosreport script
#!/bin/bash
export LANG=C

# If this script hangs, un-comment the below two entries and note the command that the script hangs on.  Then comment out that command and re-run the script.
# set -x
# set -o verbose

[[ -d /tmp/sosreport ]] && rm -rf /tmp/sosreport
mkdir /tmp/sosreport && cd /tmp/sosreport && mkdir -p  var/log etc/lvm etc/sysconfig network storage sos_commands/networking

echo -e "Gathering system information…”
hostname &> hostname  
cp -a /etc/redhat-release  ./etc/ 2>> error_log
uptime &> uptime 

echo -e "Gathering application information…”
chkconfig --list &> chkconfig
top -bn1 &> top_bn1
service --status-all &> service_status_all
date &> date
ps auxww &> ps_auxww
ps -elf &> ps_-elf
rpm -qa --last &> rpm-qa
echo -e "Running 'rpm -Va'. This may take a moment.”
rpm -Va &> rpm-Va

echo -e "Gathering memory information…”
free -m &> free  
vmstat 1 10 &> vmstat

echo -e "Gathering network information…”
ifconfig &> ./network/ifconfig  
netstat -s &>./network/netstat_-s
netstat -agn &> ./network/netstat_-agn
netstat -neopa &> ./network/netstat_-neopa
route -n &> ./network/route_-n
for i in $(ls /etc/sysconfig/network-scripts/{ifcfg,route,rule}-*) ; do echo -e "$i\n..................."; cat $i;echo " ";  done &> ./sos_commands/networking/ifcfg-files    
for i in $(ifconfig | grep "^[a-z]" | cut -f 1 -d " "); do echo -e "$i\n..................." ; ethtool $i; ethtool -k $i; ethtool -S $i; ethtool -i $i;echo -e "\n" ; done &> ./sos_commands/networking/ethtool.out
cp /etc/sysconfig/network ./sos_commands/networking/ 2>> error_log
cp /etc/sysconfig/network-scripts/ifcfg-* ./sos_commands/networking/ 2>> error_log
cp /etc/sysconfig/network-scripts/route-* ./sos_commands/networking/ 2>> error_log
cat /proc/net/bonding/bond* &> ./sos_commands/networking/proc-net-bonding-bond 2>> error_log
iptables --list --line-numbers &> ./sos_commands/networking/iptables_--list_--line-numbers
ip route show table all &> ./sos_commands/networking/ip_route_show_table_all
ip link &> ./sos_commands/networking/ip_link

echo -e "Gathering Storage/Filesystem information…”
df -l &> df
fdisk -l &> fdisk
parted -l &> parted
cp -a /etc/fstab  ./etc/ 2>> error_log
cp -a /etc/lvm/lvm.conf ./etc/lvm/ 2>> error_log
cp -a /etc/lvm/backup/ ./etc/lvm/ 2>> error_log
cp -a /etc/lvm/archive/ ./etc/lvm/ 2>> error_log
cp -a /etc/multipath.conf ./etc/ 2>> error_log
cat /proc/mounts &> mount  
iostat -tkx 1 10 &> iostat_-tkx_1_10
parted -l &> storage/parted_-l
vgdisplay -v &> storage/vgdisplay
lvdisplay &> storage/lvdisplay
pvdisplay &> storage/pvdisplay
pvs -a -v &> storage/pvs
vgs -v &> storage/vgs
lvs -o +devices &> storage/lvs
multipath -v4 -ll &> storage/multipath_ll
pvscan -vvvv &> storage/pvscan
vgscan -vvvv &> storage/vgscan
lvscan -vvvv &> storage/lvscan
lsblk &> storage/lsblk
lsblk -t &> storage/lsblk_t
dmsetup info -C &> storage/dmsetup_info_c
dmsetup status &>  storage/dmsetup_status 
dmsetup table &>  storage/dmsetup_table
ls -lahR /dev &> storage/dev

echo -e "Gathering kernel information…”
cp -a /etc/security/limits.conf ./etc/ 2>> error_log
cp -a /etc/sysctl.conf ./etc/ 2>> error_log
ulimit -a &> ulimit
cat /proc/slabinfo &> slabinfo
cat /proc/interrupts &> interrupts 
cat /proc/iomem &> iomem
cat /proc/ioports &> ioports
slabtop -o &> slabtop_-o
uname -a &> uname
sysctl -a &> sysctl_-a
lsmod &> lsmod
cp -a /etc/modprobe.conf ./etc/ 2>> error_log
cp -a  /etc/sysconfig/* ./etc/sysconfig/ 2>> error_log
for MOD in `lsmod | grep -v "Used by"| awk '{ print $1 }'`; do modinfo  $MOD 2>&1 >> modinfo; done;
ipcs -a &> ipcs_-a
ipcs -s | awk '/^0x/ {print $2}' | while read semid; do ipcs -s -i $semid; done &> ipcs_-s_verbose
sar -A &> sar_-A
cp -a /var/log/dmesg dmesg 2>> error_log
dmesg &> dmesg_now

echo -e "Gathering hardware information…”
dmidecode &> dmidecode
lspci -vvv &> lspci_-vvv
lspci &> lspci
cat /proc/meminfo &> meminfo  
cat /proc/cpuinfo &> cpuinfo

echo -e "Gathering kump information…”
cp -a /etc/kdump.conf ./etc/ 2>> error_log
ls -laR /var/crash &> ls-lar-var-crash
ls -1 /var/crash | while read n; do mkdir -p var/crash/${n}; cp -a /var/crash/${n}/vmcore-dmesg* var/crash/${n}/ 2>> error_log; done

echo -e "Gathering container related information…”
mkdir container
rpm -q podman || alias podman=“docker”
podman ps &> container/ps
podman image list &> container/image_list
podman ps | awk '$1!="CONTAINER" {print $1}' | while read id; do podman inspect $id &> container/inspect_${id}; done

echo -e "Gathering logs…”
cp -a /var/log/{containers*,message*,secure*,boot*,cron*,yum*,Xorg*,sa,rhsm,audit,dmesg} ./var/log/ 2>> error_log
cp -a /etc/*syslog.conf ./etc/ 2>> error_log

echo -e "Compressing files…”
tar -cjf /tmp/sosreport.tar.bz2 ./

echo -e "Script complete."
Object Oriented Programming

The four pillars for OOP are Abstraction, Encapsulation, Inheritance, Polymorphism.

Abstraction : Abstraction is the process of showing only essential/necessary features of an entity/object to the outside world and hide the other irrelevant information. For example to open your TV we only have a power button, It is not required to understand how infra-red waves are getting generated in TV remote control.

Encapsulation : Encapsulation means wrapping up data and member function (Method) together into a single unit i.e. class. Encapsulation automatically achieve the concept of data hiding providing security to data by making the variable as private and expose the property to access the private data which would be public.

Inheritance : The ability of creating a new class from an existing class. Inheritance is when an object acquires the property of another object. Inheritance allows a class (subclass) to acquire the properties and behavior of another class (super-class). It helps to reuse, customize and enhance the existing code. So it helps to write a code accurately and reduce the development time.

Polymorphism: Polymorphism is derived from 2 Greek words: poly and morphs. The word “poly” means many and “morphs” means forms. So polymorphism means “many forms”. A subclass can define its own unique behavior and still share the same functionalities or behavior of its parent/base class. A subclass can have their own behavior and share some of its behavior from its parent class not the other way around. A parent class cannot have the behavior of its subclass.

Hello World

A sample go program is show here.

package main

import "fmt"

func main() {
  message := greetMe("world")
  fmt.Println(message)
}

func greetMe(name string) string {
  return "Hello, " + name + "!"
}

Run the program as below:

$ go run hello.go
Variables

Normal Declaration:

var msg string
msg = "Hello"

Shortcut:

msg := "Hello"
Constants
const Phi = 1.618
Strings
str := "Hello"

Multiline string

str := `Multiline
string`
Numbers

Typical types

num := 3          // int
num := 3.         // float64
num := 3 + 4i     // complex128
num := byte('a')  // byte (alias for uint8)

Other Types

var u uint = 7        // uint (unsigned)
var p float32 = 22.7  // 32-bit float
Arrays
// var numbers [5]int
numbers := [...]int{0, 0, 0, 0, 0}
Pointers
func main () {
  b := *getPointer()
  fmt.Println("Value is", b)
func getPointer () (myPointer *int) {
  a := 234
  return &a
a := new(int)
*a = 234

Pointers point to a memory location of a variable. Go is fully garbage-collected.

Type Conversion
i := 2
f := float64(i)
u := uint(i)
Slice
slice := []int{2, 3, 4}
slice := []byte("Hello")
Condition
if day == "sunday" || day == "saturday" {
  rest()
} else if day == "monday" && isTired() {
  groan()
} else {
  work()
}
if _, err := doThing(); err != nil {
  fmt.Println("Uh oh")
Switch
switch day {
  case "sunday":
    // cases don't "fall through" by default!
    fallthrough

  case "saturday":
    rest()

  default:
    work()
}
Loop
for count := 0; count <= 10; count++ {
  fmt.Println("My counter is at", count)
}
entry := []string{"Jack","John","Jones"}
for i, val := range entry {
  fmt.Printf("At position %d, the character %s is present\n", i, val)
n := 0
x := 42
for n != x {
  n := guess()
}
Condition
if day == "sunday" || day == "saturday" {
  rest()
} else if day == "monday" && isTired() {
  groan()
} else {
  work()
}
if _, err := doThing(); err != nil {
  fmt.Println("Uh oh")
Operator Install Plan
# Find which IP need approval
oc get ip -n my-project -o=jsonpath='{.items[?(@.spec.approved==false)].metadata.name}'

# Batch approve all IPs
oc patch installplan $(oc get ip -n my-project-o=jsonpath='{.items[?(@.spec.approved==false)].metadata.name}') -n my-project --type merge --patch '{"spec":{"approved":true}}'  
RBAC

A ClusterRole|Role defines a set of permissions and where it is available, in the whole cluster or just a single Namespace.

A ClusterRoleBinding|RoleBinding connects a set of permissions with an account and defines where it is applied, in the whole cluster or just a single Namespace.

Because of this there are 4 different RBAC combinations and 3 valid ones:

Role + RoleBinding (available in single Namespace, applied in single Namespace)
ClusterRole + ClusterRoleBinding (available cluster-wide, applied cluster-wide)
ClusterRole + RoleBinding (available cluster-wide, applied in single Namespace)
Role + ClusterRoleBinding (NOT POSSIBLE: available in single Namespace, applied cluster-wide)

Etcd Snapshot & Restore
export ETCDCTL_API=3
etcdctl snapshot save --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --endpoints=127.0.0.1:2379 /opt/etcd-backup.db

etcdctl --data-dir=/root/etcd-from-backup --endpoints=https://172.0.0.8:2379 \
  --cert=/root/kubernetes/pki/etcd/server.crt \
  --key=/root/kubernetes/pki/etcd/server.key \
  --cacert=/root/kubernetes/pki/etcd/ca.crt \
  snapshot restore /opt/etcd-backup.db
BGP Summary

Protocol type: Path Vector
Type: EGP (External Gateway Protocol)
Packet Types: Open, Update, KeepAlive, Notification
Administrative Distance: eBGP: 20; iBGP: 200
Transport: TCP port 179
Keepalive 60 sec, hold timer 180
Neighbor States: Idle -> Active -> Connect -> Open Sent -> Open Confirm -> Established

1 – Idle: the initial state of a BGP connection. In this state, the BGP speaker is waiting for a BGP start event, generally either the establishment of a TCP connection or the re-establishment of a previous connection. Once the connection is established, BGP moves to the next state.
2 – Connect: In this state, BGP is waiting for the TCP connection to be formed. If the TCP connection completes, BGP will move to the OpenSent stage; if the connection cannot complete, BGP goes to Active.
3 – Active: In the Active state, the BGP speaker is attempting to initiate a TCP session with the BGP speaker it wants to peer with. If this can be done, the BGP state goes to OpenSent state.
4 – OpenSent: the BGP speaker is waiting to receive an OPEN message from the remote BGP speaker
5 – OpenConfirm: Once the BGP speaker receives the OPEN message and no error is detected, the BGP speaker sends a KEEPALIVE message to the remote BGP speaker.
6 – Established: All of the neighbor negotiations are complete. You will see a number, which tells us the number of prefixes the router has received from a neighbor or peer group.

Path Selection Attributes: (highest) Weight > (highest) Local Preference > Originate > (shortest) AS Path > Origin > (lowest) MED > External > IGP Cost > eBGP Peering > (highest) Router ID

(Originate: prefer routes that it installed into BGP by itself over a route that another router installed in BGP)

Authentication: MD5

BGP Origin codes: i – IGP (injected by “network” statement), e – EGP, ? – Incomplete

AS number range: Private AS range: 64512 – 65535, Globally (unique) AS: 1 – 64511

IBGP - can form over hops but use full mesh other routing to next hop does not work (unless IGP is setup, bgp session between 2 loopbacks). IGP synchronization must be IGP is not used for forwarding transit packets. (Redistribute ebgp to igp then back to ebgp). peer between loopbacks for redundancy using update-source lo0 command.

EBGP multihop command with TTL. also if update-source for lo0 add static route for connectivity

^ is mutually exclusive with ttl-security hops x

Inject prefix using network (local, static or igp route in table) or redistribute if router does not know how to reach the next hop of prefix, it won’t advertise to other router. make external subnets known internal is risk, use next-hop-self

Origin has not much use as EGP is obsolete. IGP(network), EGP, incomplete(redistribute)

Aggregate route using Null0 static address or aggregate-address command

Atomic_aggregate attribute - indicates prefix is aggregate and not actual destination. not much use

aggregator attribute - as number and router id originating router

AS_SET - unordered list of all ASN of all prefix belonging to aggregate rarely used

ip prefix-list filter ip as-path access-list filter

Originator_id and cluster_list prevent loops when using route reflector

confiderations is similar to route reflector. break into sub-AS. But local-pref, med and next hop are preserved within whole confideration

BGP Path Selection
  1. Prefer the path with the highest WEIGHT.
  2. Prefer the path with the highest LOCAL_PREF.
  3. Prefer the path that was locally originated via a network or aggregate BGP subcommand or through redistribution from an IGP. Local paths that are sourced by the network or redistribute commands are preferred over local aggregates that are sourced by the aggregate-address command.
  4. Prefer the path with the shortest AS_PATH.
  5. Prefer the path with the lowest origin type.
  6. Prefer the path with the lowest multi-exit discriminator (MED).
  7. Prefer eBGP over iBGP paths.
  8. Prefer the path with the lowest IGP metric to the BGP next hop.
  9. Determine if multiple paths require installation in the routing table for BGP Multipath.
  10. When both paths are external, prefer the path that was received first (the oldest one).
  11. Prefer the route that comes from the BGP router with the lowest router ID.
  12. If the originator or router ID is the same for multiple paths, prefer the path with the minimum cluster list length.
  13. Prefer the path that comes from the lowest neighbor address.

“We Love Oranges AS Oranges Mean Pure Refreshment”

Multicast

PIM dense mode (PIM-DM) uses a push model to flood multicast traffic to every corner of the network. This push model is a brute-force method of delivering data to the receivers. This method would be efficient in certain deployments in which there are active receivers on every subnet in the network. PIM-DM initially floods multicast traffic throughout the network. Routers that have no downstream neighbors prune the unwanted traffic. This process repeats every 3 minutes.

PIM Sparse Mode (PIM-SM) uses a pull model to deliver multicast traffic. Only network segments with active receivers that have explicitly requested the data receive the traffic. PIM-SM distributes information about active sources by forwarding data packets on the shared tree. Because PIM-SM uses shared trees (at least initially), it requires the use of an RP. The RP must be administratively configured in the network.

A rendezvous point (RP) is required only in networks running Protocol Independent Multicast sparse mode (PIM-SM). By default, the RP is needed only to start new sessions with sources and receivers. The concept of joining the rendezvous point (RP) is called the RPT (Root Path Tree) or shared distribution tree. The RP is the root of our tree which decides where to forward multicast traffic to. Each multicast group might have different sources and receivers so we might have different RPTs in our network.

PIM-DM supports only source trees – that is, (S,G) entries–and cannot be used to build a shared distribution tree.

IGMP is used to dynamically register individual hosts in a multicast group on a particular LAN. Enabling PIM on an interface also enables IGMP. IGMP provides a means to automatically control and limit the flow of multicast traffic throughout your network with the use of special multicast queriers and hosts.

A querier is a network device, such as a router, that sends query messages to discover which network devices are members of a given multicast group.

A host is a receiver, including routers, that sends report messages (in response to query messages) to inform the querier of a host membership. Hosts use IGMP messages to join and leave multicast groups.

Hosts identify group memberships by sending IGMP messages to their local multicast device. Under IGMP, devices listen to IGMP messages and periodically send out queries to discover which groups are active or inactive on a particular subnet.

OSPF Overview

A classless routing protocol.
Supports VLSM, CIDR, manual route summarization, equal cost load balancing.
Incremental updates are supported.
Uses only one parameter as the metric – the interface cost.
The administrative distance of OSPF routes is, by default, 110.
Uses multicast addresses 224.0.0.5 and 224.0.0.6 for routing updates.

OSPF router ID selection:

OSPF uses the following criteria to select the router ID:

  1. Manual configuration of the router ID (via the “router-id x.x.x.x” command under OSPF router configuration mode).
  2. Highest IP address on a loopback interface.
  3. Highest IP address on a non-loopback and active (no shutdown) interface.

OSPF forms neighbor relationship with other OSPF routers on the same segment by exchanging hello packets. The hello packets contain various parameters. Some of them should match between neighboring routers. These include:

  • Hello and Dead intervals
  • Area ID
  • Authentication type and password
  • Stub Area flag
  • Subnet ID and Subnet mask

When OSPF is run on a network, two important events happen before routing information is exchanged:

  • Neighbors are discovered using multicast hello packets.
  • DR and BDR are elected for every multi-access network to optimize the adjacency building process. All the routers in that segment should be able to communicate directly with the DR and BDR for proper adjacency (in the case of a point-to-point network, DR and BDR are not necessary since there are only two routers in the segment, and hence the election does not take place). For a successful neighbor discovery on a segment, the network must allow broadcasts or multicast packets to be sent.

In an NBMA network topology, which is inherently nonbroadcast, neighbors are not discovered automatically. OSPF tries to elect a DR and a BDR due to the multi-access nature of the network, but the election fails since neighbors are not discovered. Neighbors must be configured manually to overcome these problems

Each OSPF area only allows some specific LSAs to pass through. Below is a summarization of which LSAs are allowed in each OSPF area:

Area – Restriction
Normal – None
Stub – No Type 5 AS-external LSA allowed
Totally Stub – No Type 3, 4 or 5 LSAs allowed except the default summary route
NSSA – No Type 5 AS-external LSAs allowed, but Type 7 LSAs that convert to Type 5 at the NSSA ABR can traverse
NSSA Totally Stub – No Type 3, 4 or 5 LSAs except the default summary route, but Type 7 LSAs that convert to Type 5 at the NSSA ABR are allowed

OSPF States

When OSPF neighbor relationship is formed, a router goes through several state changes before it becomes fully adjacent with its neighbor. The states are Down -> Attempt (optional) -> Init -> 2-Way -> Exstart -> Exchange -> Loading -> Full. Short descriptions about these states are listed below:

𝐃𝐨𝐰𝐧: no information (hellos) has been received from this neighbor

𝐀𝐭𝐭𝐞𝐦𝐩𝐭: only valid for manually configured neighbors in an NBMA environment. In Attempt state, the router sends unicast hello packets every poll interval to the neighbor, from which hellos have not been received within the dead interval

𝐈𝐧𝐢𝐭: specifies that the router has received a hello packet from its neighbor, but the receiving router’s ID was not included in the hello packet

𝟐-𝐖𝐚𝐲: indicates bi-directional communication has been established between two routers

𝐄𝐱𝐬𝐭𝐚𝐫𝐭: Once the DR and BDR are elected, the actual process of exchanging link state information can start between the routers and their DR and BDR

𝐄𝐱𝐜𝐡𝐚𝐧𝐠𝐞: OSPF routers exchange and compare database descriptor (DBD) packets

𝐋𝐨𝐚𝐝𝐢𝐧𝐠: In this state, the actual exchange of link state information occurs. Outdated or missing entries are also requested to be resent

𝐅𝐮𝐥𝐥: routers are fully adjacent with each other

OSPF Summarization

OSPF offers two methods of route summarization:

  1. Summarization of internal routes performed on the ABRs

  2. Summarization of external routes performed on the ASBRs

  3. To summarize routes at the area boundary (ABRs), use the command: area area-id range ip-address mask [advertise | not-advertise] [cost cost]

An internal summary route is generated if at least one subnet within the area falls in the summary address range and the summarized route metric is equal to the lowest cost of all the subnets within the summary address range. Interarea summarization can only be done for the intra-area routes of connected areas, and the ABR creates a route to Null0 to avoid loops in the absence of more specific routes.

  1. To summarize external routes on the domain boundary (ASBRs), use the command: summary-address {{ip-address mask} | {prefix mask}} [not-advertise] [tag tag] The ASBR will summarize external routes before injecting them into the OSPF domain as type 5 external LSAs.

Note: An exception of using the “summary-address” is at the boundary of a NSSA area.

In both methods of route summarization described above, a summarized route is only generated if at least one subnet in the routing table falls in the summary address range.

Summarization in EIGRP and OSPF

Unlike OSPF where we can summarize only on ABR or ASBR, in EIGRP we can summarize anywhere.

Manual summarization can be applied anywhere in EIGRP domain, on every router, on every interface via the ip summary-address eigrp as-number address mask [administrative-distance ] command (for example: ip summary-address eigrp 1 192.168.16.0 255.255.248.0). Summary route will exist in routing table as long as at least one more specific route will exist. If the last specific route will disappear, summary route also will fade out. The metric used by EIGRP manual summary route is the minimum metric of the specific routes.

OSPF LSA Types

𝐑𝐨𝐮𝐭𝐞𝐫 𝐥𝐢𝐧𝐤 𝐋𝐒𝐀 (𝐓𝐲𝐩𝐞 𝟏) – Each router generates a Type 1 LSA that lists its active interfaces, IP addresses, neighbors and the cost to each. LSA Type 1 is only flooded inside the router’s area, it does not cross ABR. E bit indicates boundary router. used when connected to another domain/ redistribution B bit - indicate if it is ABR V bit - indicate endpoint for virtual link

𝐍𝐞𝐭𝐰𝐨𝐫𝐤 𝐥𝐢𝐧𝐤 𝐋𝐒𝐀 (𝐓𝐲𝐩𝐞 𝟐) – is sent out by the designated router (DR) and lists all the routers on the segment it is adjacent to. Types 2 are flooded within its area only; does not cross ABR. Type 1 & type 2 are the basis of SPF path selection.

𝐒𝐮𝐦𝐦𝐚𝐫𝐲 𝐥𝐢𝐧𝐤 𝐋𝐒𝐀 (𝐓𝐲𝐩𝐞 𝟑) – ABRs generate this LSA to send between areas (so type 3 is called inter-area link). It gathers information it has learned on one of its attached areas and summarizes them before sending out to another area. LSAs Type 3 are injected by the ABR from the backbone area into other areas and from other areas into the backbone area.

𝐒𝐮𝐦𝐦𝐚𝐫𝐲 𝐀𝐒𝐁𝐑 𝐋𝐒𝐀 (𝐓𝐲𝐩𝐞 𝟒) – Generated by the ABR to describe an ASBR to routers in other areas so that routers in other areas know how to get to external routes through that ASBR.

𝐄𝐱𝐭𝐞𝐫𝐧𝐚𝐥 𝐋𝐢𝐧𝐤 𝐋𝐒𝐀 (𝐋𝐒𝐀 𝟓) – Generated by ASBR to describe routes redistributed into the area and point the destination for these external routes to the ASBR. These routes appear as O E1 or O E2 in the routing table. O E1 - external cost and internal ospf cost added O E2 - static cost. cost does not change

𝐌𝐮𝐥𝐭𝐢𝐜𝐚𝐬𝐭 𝐋𝐒𝐀 (𝐓𝐲𝐩𝐞 𝟔) – specialized LSAs that are used in multicast OSPF applications. Cisco does not support it.

𝐍𝐒𝐒𝐀 𝐄𝐱𝐭𝐞𝐫𝐧𝐚𝐥 𝐋𝐒𝐀 (𝐓𝐲𝐩𝐞 𝟕) – Generated by an ASBR inside a Not So Stubby Area (NSSA) to describe routes redistributed into the NSSA. LSA 7 is translated into LSA 5 as it leaves the NSSA. These routes appear as N1 or N2 in the routing table inside the NSSA. Much like LSA 5, N2 is a static cost while N1 is a cumulative cost that includes the cost upto the ASBR.