Techtip – Determining Optic connectors using Cisco IOS

Something that has frustrated me in the past is using the cumbersome method of determining the connectors required to terminate a particular optic’s fibres. We would determine the optic part code (show inventory, show module, etc) and then looked up the partcode on CCO. This was incredibly inefficient and I always felt that there had to be a way of doing this through the command line so, after many CCO documents, I found the following.

show idprom int <interface>

will show the connector type.

IOS

The following is an output from a 7600. The cards in slot 1 and 2 are LAN based (67xx) cards. The ES+ in slots 3 and 4 are Ethernet Services cards, which behaves less like a classic LAN interfaces and more like a genuine router interface, with support for CBWFQ / MQC and other features commonly found on Cisco’s software router platforms, such as a 7200.

Router#sh mod
Mod Ports Card Type                              Model              Serial No.
--- ----- -------------------------------------- ------------------ -----------
  1    8  CEF720 8 port 10GE with DFC            WS-X6708-10GE
  2   24  CEF720 24 port 1000mb SFP              WS-X6724-SFP
  3    2  7600 ES+                               7600-ES+2TG3CXL
  4    4  7600 ES+T                              76-ES+T-4TG

Some examples (filtered just to show the relevant connector lines):

Router#show idprom int tengig 1/1 | i connector
Optical connector type               :0x1 =SC
Router#show idprom int gig 2/1 | i Connector   
 Connector         : LC [0x07]
Router#show idprom int tengig 3/1 | i Connector
  Connector type                            = LC.
Router#show idprom int tengig 4/1 | i Connector
  Connector type                            = LC.

CRS

CRS is (of course) different:

RP/0/RP0/CPU0:Router#show diag 0/0/CPU0  | i Connector
Fri Jul  1 13:45:21.768 UTC
  Connector type:  SC

With these commands you’ll be able to determine what your connector types are without referring to product sheets.

Share

Cisco LISP – Multihoming

This is part of a series of posts – The Lisp Papers.

Overview

One of the key functions of the LISP implementation is baked-in multihoming and traffic engineering. EID spaces can be connected to the RLOC environment via several ETRs. The ETR responding to the querying ITR can offer a list of ETRs to be used. The LISP designers had two objectives when they were determining how this should function.

Firstly, the design should offer a preference of some ETRs over others. This allows some systems to act as primary ETRs and others as backups. This is implemented using the Priority field, with lower Priority systems being (counterintuitively) preferable over higher systems.

Secondly, the design should allow traffic distribution to be controlled. Once the priority comparison has taken place and, assuming that a number of systems with the lowest priority have been identified, the weight is considered. Traffic will be distributed between ETRs in the ratio of their weights. For example, ETR A might have a weight of 80 and ETR B might have a weight of 20. Traffic will be distributed between them in a ratio of 4:1.

Cisco LISP Network

In order to fully explore the design, the topology used in the previous post has been modified as follows:

In this case, the “MF” device combines Mapping Server and Mapping Resolver functionality (MF = Multi-Function). In addition, it peers with xTR3.1 and xTR3.2, which act as dual homing xTRs for Customer C. In this topology, xTR1 and xTR2 register with MS and xTR3.1 and xTR3.2 with MF for Mapping Server functionality. xTR1 and xTR2 use MR and xTR3.1 and xTR3.2 use MF to resolve EID to RLOC addresses. MF has GRE tunnels and BGP peers to both MS and MR. This allows the EID prefixes to be disseminated throughout the network and for Mapping Requests to to be delivered to the correct RLOC address.

Design thought

This is a far more realistic topology than the one considered in the previous post for several reasons. The dual xTRs offer a resilient connection to Customer C. There remains a single point of failure in MF, which could be resolved by deploying a second MF and attaching it to a separate part of the core network. The MS and MR functionality are combined, which makes sense at a superficial level. This is for the practical reason that to separate the functions and provide resilience would require 4 systems (resilient MS and resilient MR), which would probably be an overkill for all but the largest environments. Perhaps there are scaling, security or topological reasons to separate MS and MR functionality.

The Mapping Request is routed over the ALT network, as described in the previous post, to one of the RLOCs registered for a specific EID space. The xTR that this corresponds to will respond with a list of RLOCs with associated priorities and weights.

MF’s LISP configuration looks as follows:

router lisp
 site CustomerC
  authentication-key cisco
  eid-prefix 10.1.0.0/24 accept-more-specifics
  exit
 !
 ipv4 map-server
 ipv4 map-resolver
 ipv4 alt-vrf LISP
 exit

xTR3.1 and xTR3.2 have matching configurations:

router lisp
!database mapping for xTR3.1
 database-mapping 10.1.0.0/24 10.255.255.6 priority 2 weight 50
!database mapping for xTR3.2
 database-mapping 10.1.0.0/24 10.255.255.7 priority 2 weight 50
!Configuring MF's loopback as Mapping Resolver
 ipv4 itr map-resolver 10.255.255.5
 ipv4 itr
!Configuring MF's loopback as Mapping Server
 ipv4 etr map-server 10.255.255.5 key cisco
 ipv4 etr
 exit

Pitfall alert

ETRs must be configured with all the EID address space database mappings for which they are authoritative for. In the above example, xTR3.1 is configured with database mappings for both xTR3.1 and xTR3.2. This makes sense when you consider that any ETR could respond to a mapping request and will need to respond with the addresses, priority and weight for the associated ETR RLOC addresses for a required EID address space. If you only configure xTR3.1 with the database mappings for xTR3.1, it will only respond with its own RLOC address and no load-balancing or resilience will be delivered.

Examining the LISP EID database table on MF shows that both xTRs have registered with it:

MF#sh lisp site detail 
LISP Site Registration Information

Site name: CustomerC
Allowed configured locators: any
Allowed EID-prefixes:
  EID-prefix: 10.1.0.0/24 
    First registered:     00:47:03
    Routing table tag:    0x0
    Origin:               Configuration, accepting more specifics
    Registration errors:  
      Authentication failures:   0
      Allowed locators mismatch: 0
    ETR 10.1.3.26, last registered 00:00:41, no proxy-reply, no map-notify
                   TTL 1d00h
      Locator       Local  State      Pri/Wgt
      10.255.255.6  no     up           2/50 
      10.255.255.7  yes    up           2/50 
    ETR 10.1.3.22, last registered 00:00:53, no proxy-reply, no map-notify
                   TTL 1d00h
      Locator       Local  State      Pri/Wgt
      10.255.255.6  yes    up           2/50 
      10.255.255.7  no     up           2/50 

If Customer A wishes to communicate with Customer C, xTR1 will send a Mapping Request to MR. MR will forward this over the ALT network, via the GRE tunnel between itself and MF, to the Customer C address, as detailed in the following packet trace:

Frame 1: 126 bytes on wire (1008 bits), 126 bytes captured (1008 bits)
Ethernet II, Src: ca:00:16:79:00:8c (ca:00:16:79:00:8c), Dst: ca:03:16:79:00:1c (ca:03:16:79:00:1c)
Internet Protocol, Src: 10.255.255.0 (10.255.255.0), Dst: 10.255.255.5 (10.255.255.5)
Generic Routing Encapsulation (IP)
Internet Protocol, Src: 10.1.1.1 (10.1.1.1), Dst: 10.1.0.255 (10.1.0.255)
User Datagram Protocol, Src Port: lisp-control (4342), Dst Port: lisp-control (4342)
Locator/ID Separation Protocol
    0001 .... .... .... .... .... = Type: Map-Request (1)
    .... 0... .... .... .... .... = A bit (Authoritative): Not set
    .... .1.. .... .... .... .... = M bit (Map-Reply present): Set
    .... ..0. .... .... .... .... = P bit (Probe): Not set
    .... ...0 .... .... .... .... = S bit (Solicit-Map-Request): Not set
    .... .... 0... .... .... .... = p bit (Proxy ITR): Not set
    .... .... .0.. .... .... .... = s bit (SMR-invoked): Not set
    .... .... ..00 0000 000. .... = Reserved bits: 0x000000
    .... .... .... .... ...0 0000 = ITR-RLOC Count: 0
    Record Count: 1
    Nonce: 0x0f5c25e246fd29d7
    Source EID AFI: 1
    Source EID: 10.1.1.2 (10.1.1.2)
    ITR-RLOC 1: 10.255.255.1
        ITR-RLOC-AFI: 1
        ITR-RLOC Address: 10.255.255.1 (10.255.255.1)
    Record 1: 10.1.0.255/32
        Reserved bits: 0x00
        Prefix length: 32
        Prefix AFI: 1
        Prefix: 10.1.0.255
    Map-Reply record
        EID prefix: 10.1.1.0/24, TTL: 1440, Authoritative, No-Action
            0000 .... .... .... = Reserved: 0x0000
            .... 0000 0000 0000 = Mapping Version: 0
            Local RLOC: 10.255.255.1, Reachable, Priority/Weight: 2/50, Multicast Priority/Weight: 255/0

You will notice that the above packet trace contains a GRE header sourced by MR and destined to MF. This is because the packet capture occured between Core and MF. The response below from xTR3.1 is not sent via the ALT (therefore no GRE header) and includes two RLOCs, a local RLOC (for xTR3.1) and an additional RLOC (xTR3.2):

Frame 2: 94 bytes on wire (752 bits), 94 bytes captured (752 bits)
Ethernet II, Src: ca:03:16:79:00:1c (ca:03:16:79:00:1c), Dst: ca:00:16:79:00:8c (ca:00:16:79:00:8c)
Internet Protocol, Src: 10.1.3.22 (10.1.3.22), Dst: 10.255.255.1 (10.255.255.1)
User Datagram Protocol, Src Port: lisp-control (4342), Dst Port: lisp-control (4342)
Locator/ID Separation Protocol
    0010 .... .... .... .... .... = Type: Map-Reply (2)
    .... 0... .... .... .... .... = P bit (Probe): Not set
    .... .0.. .... .... .... .... = E bit (Echo-Nonce locator reachability algorithm enabled): Not set
    .... ..00 0000 0000 0000 0000 = Reserved bits: 0x000000
    Record Count: 1
    Nonce: 0x0f5c25e246fd29d7
    EID prefix: 10.1.0.0/24, TTL: 1440, Authoritative, No-Action
        0000 .... .... .... = Reserved: 0x0000
        .... 0000 0000 0000 = Mapping Version: 0
        Local RLOC: 10.255.255.6, Reachable, Priority/Weight: 2/50, Multicast Priority/Weight: 255/0
        RLOC: 10.255.255.7, Reachable, Priority/Weight: 2/50, Multicast Priority/Weight: 255/0

Use the following table to decipher the traces, or for more detail, refer to the detailed diagram and configurations:

SystemTypeAddress
CustomerAEID10.1.1.2
xTR1EID10.1.1.1
xTR1loopback10.255.255.1
MRloopback10.255.255.0
MFloopback10.255.255.5
XTR3.1loopback10.255.255.6
XTR3.1RLOC10.1.3.22
xTR3.2loopback10.255.255.7
xTR3.2RLOC10.1.3.26
Customer CEID10.1.0.255

Examining the FIB on xTR1 shows that both RLOCs are used:

xTR1#sh ip cef 10.1.0.255
10.1.0.0/24
  nexthop 10.1.0.0 Null0
xTR1#sh ip cef 10.1.0.255 det
10.1.0.0/24, epoch 0, flags subtree context, check lisp eligibility
  SC owned: LISP remote EID - locator status bits 0x00000003
  LISP remote EID: 4 packets 400 bytes fwd action encap
  LISP source path list
    nexthop 10.255.255.6 LISP0
    nexthop 10.255.255.7 LISP0
  2 IPL sources [active source]
   Dependent covered prefix type inherit cover 0.0.0.0/0
  recursive via 0.0.0.0/0
    attached to Null0

You might have observed that the interface LISP0 on xTR1 has an extra line of config.

interface LISP0
 ip load-sharing per-packet

This will share packets in a round-robin fashion between xTR3.1 and xTR3.2. This is probably not desirable as using different paths within a stream could cause out of sequence errors and excessive retransmissions, which is why the default is per-destination.

Summary

In the networks of today, load-balancing and resilience is predominantly delivered by the crude tools of deaggregation and AS Path prepending. LISP offers a much more subtle and manageable toolkit in a way that doesn’t beggar thy neighbour.

Share

LISP – Separate MS / MR

This is part of a series of posts – The Lisp Papers.

In the previous LISP post, Practical LISP – Basic Control Plane, the network topology had a single device that delivered both MS and MR functions. While this demonstrated a simple LISP network, it is not a practical deployment. In reality, any number of MS and MR devices will communicate over an Alternative Logical Topology (ALT).

An ALT is nothing more than a tunnelled overlay network that runs BGP to disseminate EID addresses. It also acts as the environment that delivers Mapping Requests or data probes. The Mapping Request / Reply action has been largely covered under the previous post. Data Probes weren’t.

Data Probes

Data Probes are used to ensure that the first initial frames aren’t dropped while a Mapping Request is sent and Response is received. This delay is similar to DNS but with a small proviso. As DNS requests occur within the client, the dropping of the first few frames doesn’t occur as the network layer isn’t engaged until a destination address has been resolved. However, the LISP map doesn’t occur in the client stack and an ITR will not buffer the frames until the destination ETR(s) have been located. As such, a few packets will generally be dropped until the Mapping Response has been received.

To get around this, Data Probes can be used. This is quite simply using the initial packets received by the ITR to act as a mapping request. The data packet is encapsulated with a LISP header and forwarded to the MR. The LISP packet addressed to the EID and encapsulated within a GRE header, which is destination addressed to the next hop specified by the BGP routing used over the ALT. The GRE packet will potentially be decapsulated and encapsulated multiple times as it traverses the ALT. The ALT will use BGP routing to forward the packet to the EID prefix source, which is the MS. Once at the MS, the LISP packet is forwarded on to the ETR, where the Data Packet is decapsulated and forwarded on to the EID Destination.

So we have 3 different levels of source / destination addresses, which can best be understood using the following diagram:
Location ID Separation Protocol Data Probe

Data Probes seem to be a good idea, but the ALT draft does draw attention to some concerns:

It is worth noting that there has been a great deal of discussion and controversy about whether Data Probes are a good idea. On the one hand, using them offers a method of avoiding the “first packet drop” problem when an ITR does not have a mapping for a particular EID-prefix. On the other hand, forwarding data packets on the ALT would require that it either be engineered to support relatively high traffic rates, which is not generally feasible for a tunneled network, or that it be carefully designed to aggressively rate-limit traffic to avoid congestion or DoS attacks. There may also be issues caused by different latency or other performance characteristics between the ALT path taken by an initial Data Probe and the “Internet” path taken by subsequent packets on the same flow once a mapping is in place on an ITR. For these reasons, the use of Data Probes is not recommended at this time; they should only be originated an ITR when explicitly configured to do so and such configuration should only be enabled when performing experiments intended to test the viability of using Data Probes.

Cisco provides support for data probes on the Nexus platform using the command:
ip lisp itr send-data-probe
No support for data probes seems to be available in IOS (15.1(4)XB4 or 15.1.4M).

The ALT

The ALT does not directly communicate the RLOC to EID mapping. It simply provides a low-capacity environment to deliver the initial Mapping Requests, addressed to the EID required. The Mapping response will traverse the standard RLOC environment, with the source the responding ETR and the destination would be the requesting ITR.

To explore the configuration required to support a separated MS and MR function connecting over the ALT, the following topology will be used:
Locator / ID Separation Protocol MS MR over ALT
The configurations use the new LISP CLI format.
MR Configuration
The MR configuration now includes a GRE tunnel to the MS and an IPv4 VRF SAFI BGP peer to the remote side of the BGP peer tunnel. LISP is redistributed into this BGP SAFI.

vrf definition LISP
 rd 1:1
 !
 address-family ipv4
 exit-address-family
!
interface Loopback0
 ip address 10.255.255.0 255.255.255.255
!
interface Tunnel0
 vrf forwarding LISP
 ip address 10.0.0.1 255.255.255.252
 tunnel source Loopback0
 tunnel destination 10.255.255.4
!
router lisp
 ipv4 map-resolver
 ipv4 alt-vrf LISP
 exit
!
router bgp 65001
 bgp log-neighbor-changes
 !
 address-family ipv4 vrf LISP
  redistribute lisp
  neighbor 10.0.0.2 remote-as 65002
  neighbor 10.0.0.2 activate
 exit-address-family

MS Configuration
The reciprocal configuration is specified

vrf definition LISP
 rd 1:1
 !
 address-family ipv4
 exit-address-family
!
interface Loopback0
 ip address 10.255.255.4 255.255.255.255
!
interface Tunnel0
 vrf forwarding LISP
 ip address 10.0.0.2 255.255.255.252
 tunnel source Loopback0
 tunnel destination 10.255.255.0
!
router lisp
 site CustomerA
  authentication-key cisco
  eid-prefix 10.1.1.0/24 accept-more-specifics
  exit
 !
 site CustomerB
  authentication-key cisco
  eid-prefix 10.1.2.0/24 accept-more-specifics
  exit
 !
 ipv4 map-server
 ipv4 alt-vrf LISP
 exit
!
router bgp 65002
 bgp log-neighbor-changes
 !
 address-family ipv4 vrf LISP
  redistribute lisp
  neighbor 10.0.0.1 remote-as 65001
  neighbor 10.0.0.1 activate
 exit-address-family

xTRs modified configuration
Previously, the xTRs pointed to a single address for both the MS and MR addresses. Now we point the MS and MR elements in the xTR configuration to the separate addresses specified above:
xTR1

router lisp
 database-mapping 10.1.1.0/24 10.255.255.1 priority 2 weight 50
 ipv4 itr map-resolver 10.255.255.0
 ipv4 itr
 ipv4 etr map-server 10.255.255.4 key cisco
 ipv4 etr
 exit

xTR2

router lisp
 database-mapping 10.1.2.0/24 10.255.255.1 priority 2 weight 50
 ipv4 itr map-resolver 10.255.255.0
 ipv4 itr
 ipv4 etr map-server 10.255.255.4 key cisco
 ipv4 etr
 exit

This topology peers the MS directly with the MR. However, it is reasonable to assume that xTR1 would use a MS / MR combination and xTR2 would use another. Further, direct peering is not likely. Instead, the MR would likely peer with a chain of ALT routers before reaching the MS, similar to how the Internet operates with BGP peering from source AS to destination AS.

As BGP is used to interconnect MS and MR devices over the ALT, the standard BGP prefix aggregation mechanisms and best practices could be followed.

ALT in Action

To really get to grips with the Mapping Request, it is important to examine the packets.  The following wireshark frame captures were taken (made available here with the excellent services of Cloudshark):

xTR1 to MR
MR to MS
MS to xTR2

The Mapping Response is presented below. This bypasses the ALT and is sent directly from xTR2 to xTR1.
xTR2 to xTR1

Use the following table to decipher the traces, or for more detail, refer to the detailed diagram and configurations:

SystemTypeAddress
CustomerAEID10.1.1.2
CustomerBEID10.1.2.255
xTR1EID10.1.1.1
xTR1RLOC10.1.3.2
xTR1loopback10.255.255.1
MRtunnel endpoint10.0.0.1
MStunnel endpoint10.0.0.2
MRloopback10.255.255.0
MSloopback10.255.255.4
MSRLOC10.1.3.10
xTR2RLOC10.1.3.6
xTR2loopback10.255.255.2

Monitoring the ALT Network
The MR now contains a couple BGP prefixes within the LISP VRF:

MR#sh ip bgp vpnv4 vrf LISP
BGP table version is 3, local router ID is 10.255.255.0
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, x best-external, f RT-Filter
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 1:1 (default for vrf LISP)
*> 10.1.1.0/24      10.0.0.2                 1             0 65002 ?
*> 10.1.2.0/24      10.0.0.2                 1             0 65002 ?

The networks 10.1.1.0/24 and 10.1.2.0/24 are the EIDs address spaces for Customer A and Customer B, respectively. 10.0.0.2 refers to the MS tunnel endpoint, which is used to establish the BGP Peer with the MR.

Share

LISP – New CLI

The Cisco Locator/ID Separation Protocol (LISP) implementation is a next generation routing architecture and understandably has not reached the maturity level of other routing protocols. Cisco has decided to update the CLI, as of version 15.1(4)XB, released on April 18th. The good news is that the conversion from the old to new CLI happens automatically. Also, the mainline release with LISP support, 15.1.4M, makes use of the new CLI.

The following examples highlight the changes to the configuration elements:

Old New
MS
ip lisp map-server
!
lisp site CustomerA
 authentication-key cisco
 eid-prefix 10.1.1.0/24 accept-more-specifics
lisp site CustomerB
 authentication-key cisco
 eid-prefix 10.1.2.0/24 accept-more-specifics
ip lisp alt-vrf LISP
router lisp
 siteCustomerA
  authentication-key cisco
  eid-prefix 10.1.1.0/24 accept-more-specifics
  exit
 !
 site CustomerB
  authentication-key cisco
  eid-prefix 10.1.2.0/24 accept-more-specifics
  exit
 !
 ipv4 map-server
 ipv4 alt-vrf LISP
 exit
MR
ip lisp map-resolver
ip lisp alt-vrf LISP
router lisp
 ipv4 map-resolver
 ipv4 alt-vrf LISP
 exit

As is visible above, the major change is grouping the LISP commands under the router lisp section.

Share

Practical LISP – Monitoring LISP

This is part of a series of posts – The Lisp Papers.

In the previous post on LISP, we looked at the control plane. This post will look at how we monitor the connectivity provided.

To see which ETRs are registered with the MS, do the following:

MSMR#sh lisp site detail
LISP Site Registration Information

Site name: CustomerA
Allowed configured locators: any
Allowed EID-prefixes:
  EID-prefix: 10.1.1.0/24
    First registered:     00:00:59
    Routing table tag:    0x0
    Origin:               Configuration, accepting more specifics
    Registration errors:
      Authentication failures:   0
      Allowed locators mismatch: 0
    ETR 10.1.3.2, last registered 00:00:59, no proxy-reply
                  TTL 1d00h
      Locator       Local  State      Pri/Wgt
      10.255.255.1  yes    up           2/50
Site name: CustomerB
Allowed configured locators: any
Allowed EID-prefixes:
  EID-prefix: 10.1.2.0/24
    First registered:     00:00:55
    Routing table tag:    0x0
    Origin:               Configuration, accepting more specifics
    Registration errors:
      Authentication failures:   0
      Allowed locators mismatch: 0
    ETR 10.1.3.6, last registered 00:00:55, no proxy-reply
                  TTL 1d00h
      Locator       Local  State      Pri/Wgt
      10.255.255.2  yes    up           2/50
MSMR#

At this point, I would like to ask you to cast your mind back to your very first networking course. Perhaps (like me) this was the MCSE Networking Essentials or maybe the CCNA. Regardless, I would guess that it discussed the ping command. Using it every day, I had forgotten that ping is actually an acronym. Do you know what it stands for?


Packet INternet Groper

Well, the good designers and architects of LISP had not forgotten. So when they developed a ping-like application for querying the LISP Mapping Database it became, predictably, the LISP Internet Groper, or LIG.
The use of LIG is as follows:

xTR2#lig ?
  Hostname or A.B.C.D  IPv4 Destination Endpoint ID (EID)
  self                 Test if local EID-prefix is registered in the mapping database

xTR2#lig 10.1.1.0
Mapping information for EID 10.1.1.0 from 10.1.3.2 with RTT 664 msecs
10.1.1.0/24, uptime: 00:00:05, expires: 23:59:56, via map-reply, complete
  Locator       Uptime    State      Pri/Wgt
  10.255.255.1  00:00:05  up           2/50

Where 10.1.1.0 is the remote EID and 10.1.3.2 (and 10.255.255.1, which is the loopback) is the remote ETR.

The LISP forwarding table on an ITR can be examined as follows:
xTR2#sh ip lisp forwarding eid remote
Prefix                 Fwd action  Locator status bits
0.0.0.0/0              signal      0x00000000
  packets/bytes       0/0
10.1.1.0/24            encap       0x00000001
  packets/bytes       5/430

and the CEF table looks like the following:

xTR2#sh ip cef 10.1.1.0 detail
10.1.1.0/24, epoch 0, flags subtree context, check lisp eligibility
  SC owned: LISP remote EID - locator status bits 0x00000001
  LISP remote EID: 5 packets 430 bytes fwd action encap
  2 IPL sources [active source]
   Dependent covered prefix type inherit cover 0.0.0.0/0
  LISP source path list
    nexthop 10.255.255.1 LISP0
  recursive via 0.0.0.0/0
    attached to Null0
Share

Copyleft(ↄ) 2014. Text is available under the Creative Commons Attribution-ShareAlike license

Pattinson Consulting Limited