Committed by
Gerrit Code Review
[ONOS-2596] BGP Open message validation
Change-Id: I2da98830159ed57e3727aae8d02af9f438586815
Showing
2 changed files
with
209 additions
and
9 deletions
... | @@ -28,8 +28,8 @@ public final class BGPErrorType { | ... | @@ -28,8 +28,8 @@ public final class BGPErrorType { |
28 | public static final byte OPEN_MESSAGE_ERROR = 2; | 28 | public static final byte OPEN_MESSAGE_ERROR = 2; |
29 | public static final byte UPDATE_MESSAGE_ERROR = 3; | 29 | public static final byte UPDATE_MESSAGE_ERROR = 3; |
30 | public static final byte HOLD_TIMER_EXPIRED = 4; | 30 | public static final byte HOLD_TIMER_EXPIRED = 4; |
31 | - public static final byte FINITE_STATE_MACHINE_ERROR = 4; | 31 | + public static final byte FINITE_STATE_MACHINE_ERROR = 5; |
32 | - public static final byte CEASE = 5; | 32 | + public static final byte CEASE = 6; |
33 | 33 | ||
34 | //Message Header Error subcodes | 34 | //Message Header Error subcodes |
35 | public static final byte CONNECTION_NOT_SYNCHRONIZED = 1; | 35 | public static final byte CONNECTION_NOT_SYNCHRONIZED = 1; |
... | @@ -42,6 +42,7 @@ public final class BGPErrorType { | ... | @@ -42,6 +42,7 @@ public final class BGPErrorType { |
42 | public static final byte BAD_BGP_IDENTIFIER = 3; | 42 | public static final byte BAD_BGP_IDENTIFIER = 3; |
43 | public static final byte UNSUPPORTED_OPTIONAL_PARAMETER = 4; | 43 | public static final byte UNSUPPORTED_OPTIONAL_PARAMETER = 4; |
44 | public static final byte UNACCEPTABLE_HOLD_TIME = 5; | 44 | public static final byte UNACCEPTABLE_HOLD_TIME = 5; |
45 | + public static final byte UNSUPPORTED_CAPABILITY = 7; | ||
45 | 46 | ||
46 | //UPDATE Message Error subcodes | 47 | //UPDATE Message Error subcodes |
47 | public static final byte MALFORMED_ATTRIBUTE_LIST = 1; | 48 | public static final byte MALFORMED_ATTRIBUTE_LIST = 1; | ... | ... |
... | @@ -17,14 +17,20 @@ | ... | @@ -17,14 +17,20 @@ |
17 | package org.onosproject.bgp.controller.impl; | 17 | package org.onosproject.bgp.controller.impl; |
18 | 18 | ||
19 | import java.io.IOException; | 19 | import java.io.IOException; |
20 | +import java.net.InetAddress; | ||
20 | import java.net.InetSocketAddress; | 21 | import java.net.InetSocketAddress; |
21 | import java.net.SocketAddress; | 22 | import java.net.SocketAddress; |
23 | +import java.net.UnknownHostException; | ||
22 | import java.nio.channels.ClosedChannelException; | 24 | import java.nio.channels.ClosedChannelException; |
23 | import java.util.Collections; | 25 | import java.util.Collections; |
24 | import java.util.Date; | 26 | import java.util.Date; |
25 | import java.util.List; | 27 | import java.util.List; |
28 | +import java.util.LinkedList; | ||
29 | +import java.util.ListIterator; | ||
26 | import java.util.concurrent.RejectedExecutionException; | 30 | import java.util.concurrent.RejectedExecutionException; |
27 | 31 | ||
32 | +import org.jboss.netty.buffer.ChannelBuffer; | ||
33 | +import org.jboss.netty.buffer.ChannelBuffers; | ||
28 | import org.jboss.netty.channel.Channel; | 34 | import org.jboss.netty.channel.Channel; |
29 | import org.jboss.netty.channel.ChannelHandlerContext; | 35 | import org.jboss.netty.channel.ChannelHandlerContext; |
30 | import org.jboss.netty.channel.ChannelStateEvent; | 36 | import org.jboss.netty.channel.ChannelStateEvent; |
... | @@ -47,6 +53,10 @@ import org.onosproject.bgpio.protocol.BGPMessage; | ... | @@ -47,6 +53,10 @@ import org.onosproject.bgpio.protocol.BGPMessage; |
47 | import org.onosproject.bgpio.protocol.BGPOpenMsg; | 53 | import org.onosproject.bgpio.protocol.BGPOpenMsg; |
48 | import org.onosproject.bgpio.protocol.BGPType; | 54 | import org.onosproject.bgpio.protocol.BGPType; |
49 | import org.onosproject.bgpio.protocol.BGPVersion; | 55 | import org.onosproject.bgpio.protocol.BGPVersion; |
56 | +import org.onosproject.bgpio.types.BGPErrorType; | ||
57 | +import org.onosproject.bgpio.types.BGPValueType; | ||
58 | +import org.onosproject.bgpio.types.FourOctetAsNumCapabilityTlv; | ||
59 | +import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv; | ||
50 | import org.slf4j.Logger; | 60 | import org.slf4j.Logger; |
51 | import org.slf4j.LoggerFactory; | 61 | import org.slf4j.LoggerFactory; |
52 | 62 | ||
... | @@ -56,7 +66,7 @@ import org.slf4j.LoggerFactory; | ... | @@ -56,7 +66,7 @@ import org.slf4j.LoggerFactory; |
56 | class BGPChannelHandler extends IdleStateAwareChannelHandler { | 66 | class BGPChannelHandler extends IdleStateAwareChannelHandler { |
57 | 67 | ||
58 | private static final Logger log = LoggerFactory.getLogger(BGPChannelHandler.class); | 68 | private static final Logger log = LoggerFactory.getLogger(BGPChannelHandler.class); |
59 | - | 69 | + static final int BGP_MIN_HOLDTIME = 3; |
60 | static final int BGP_MAX_KEEPALIVE_INTERVAL = 3; | 70 | static final int BGP_MAX_KEEPALIVE_INTERVAL = 3; |
61 | private BGPPeer bgpPeer; | 71 | private BGPPeer bgpPeer; |
62 | private BGPId thisbgpId; | 72 | private BGPId thisbgpId; |
... | @@ -68,6 +78,13 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { | ... | @@ -68,6 +78,13 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { |
68 | private int peerIdentifier; | 78 | private int peerIdentifier; |
69 | private BGPPacketStatsImpl bgpPacketStats; | 79 | private BGPPacketStatsImpl bgpPacketStats; |
70 | static final int MAX_WRONG_COUNT_PACKET = 5; | 80 | static final int MAX_WRONG_COUNT_PACKET = 5; |
81 | + static final byte MULTI_PROTOCOL_EXTN_CAPA_TYPE = 1; | ||
82 | + static final byte FOUR_OCTET_AS_NUM_CAPA_TYPE = 65; | ||
83 | + static final int AS_TRANS = 23456; | ||
84 | + static final int MAX_AS2_NUM = 65535; | ||
85 | + static final short AFI = 16388; | ||
86 | + static final byte RES = 0; | ||
87 | + static final byte SAFI = 71; | ||
71 | 88 | ||
72 | // State needs to be volatile because the HandshakeTimeoutHandler | 89 | // State needs to be volatile because the HandshakeTimeoutHandler |
73 | // needs to check if the handshake is complete | 90 | // needs to check if the handshake is complete |
... | @@ -636,15 +653,197 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { | ... | @@ -636,15 +653,197 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { |
636 | } | 653 | } |
637 | 654 | ||
638 | /** | 655 | /** |
639 | - * Open message validation. | 656 | + * BGP open message validation. |
640 | * | 657 | * |
641 | * @param h channel handler | 658 | * @param h channel handler |
642 | - * @param pOpenmsg open message | 659 | + * @param openMsg open message |
643 | - * @return true if validation succeed, otherwise false | 660 | + * @return true if valid message, otherwise false |
644 | - * @throws BGPParseException when received invalid message | 661 | + * @throws BGPParseException throw exception |
662 | + */ | ||
663 | + public boolean openMsgValidation(BGPChannelHandler h, BGPOpenMsg openMsg) throws BGPParseException { | ||
664 | + boolean result; | ||
665 | + | ||
666 | + // Validate BGP ID | ||
667 | + result = bgpIdValidation(openMsg); | ||
668 | + if (!result) { | ||
669 | + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_BGP_IDENTIFIER, null); | ||
670 | + } | ||
671 | + | ||
672 | + // Validate AS number | ||
673 | + result = asNumberValidation(h, openMsg); | ||
674 | + if (!result) { | ||
675 | + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_PEER_AS, null); | ||
676 | + } | ||
677 | + | ||
678 | + // Validate hold timer | ||
679 | + if ((openMsg.getHoldTime() != 0) && (openMsg.getHoldTime() < BGP_MIN_HOLDTIME)) { | ||
680 | + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.UNACCEPTABLE_HOLD_TIME, null); | ||
681 | + } | ||
682 | + | ||
683 | + // Validate capabilities | ||
684 | + result = capabilityValidation(h, openMsg); | ||
685 | + return result; | ||
686 | + } | ||
687 | + | ||
688 | + /** | ||
689 | + * Capability Validation. | ||
690 | + * | ||
691 | + * @param h channel handler | ||
692 | + * @param openmsg open message | ||
693 | + * @return success or failure | ||
694 | + * @throws BGPParseException | ||
695 | + */ | ||
696 | + private boolean capabilityValidation(BGPChannelHandler h, BGPOpenMsg openmsg) throws BGPParseException { | ||
697 | + log.debug("capabilityValidation"); | ||
698 | + | ||
699 | + boolean isMultiProtocolcapabilityExists = false; | ||
700 | + boolean isFourOctetCapabilityExits = false; | ||
701 | + int capAsNum = 0; | ||
702 | + | ||
703 | + List<BGPValueType> capabilityTlv = openmsg.getCapabilityTlv(); | ||
704 | + ListIterator<BGPValueType> listIterator = capabilityTlv.listIterator(); | ||
705 | + List<BGPValueType> unSupportedCapabilityTlv = new LinkedList<>(); | ||
706 | + ListIterator<BGPValueType> unSupportedCaplistIterator = unSupportedCapabilityTlv.listIterator(); | ||
707 | + BGPValueType tempTlv; | ||
708 | + boolean isLargeAsCapabilityCfg = h.bgpconfig.getLargeASCapability(); | ||
709 | + boolean isLsCapabilityCfg = h.bgpconfig.getLsCapability(); | ||
710 | + | ||
711 | + while (listIterator.hasNext()) { | ||
712 | + BGPValueType tlv = listIterator.next(); | ||
713 | + if (tlv.getType() == MULTI_PROTOCOL_EXTN_CAPA_TYPE) { | ||
714 | + isMultiProtocolcapabilityExists = true; | ||
715 | + } | ||
716 | + if (tlv.getType() == FOUR_OCTET_AS_NUM_CAPA_TYPE) { | ||
717 | + isFourOctetCapabilityExits = true; | ||
718 | + capAsNum = ((FourOctetAsNumCapabilityTlv) tlv).getInt(); | ||
719 | + } | ||
720 | + } | ||
721 | + | ||
722 | + if (isFourOctetCapabilityExits) { | ||
723 | + if (capAsNum > MAX_AS2_NUM) { | ||
724 | + if (openmsg.getAsNumber() != AS_TRANS) { | ||
725 | + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_PEER_AS, null); | ||
726 | + } | ||
727 | + } else { | ||
728 | + if (capAsNum != openmsg.getAsNumber()) { | ||
729 | + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_PEER_AS, null); | ||
730 | + } | ||
731 | + } | ||
732 | + } | ||
733 | + | ||
734 | + if ((isLsCapabilityCfg)) { | ||
735 | + if (!isMultiProtocolcapabilityExists) { | ||
736 | + tempTlv = new MultiProtocolExtnCapabilityTlv(AFI, RES, SAFI); | ||
737 | + unSupportedCapabilityTlv.add(tempTlv); | ||
738 | + } | ||
739 | + } | ||
740 | + | ||
741 | + if ((isLargeAsCapabilityCfg)) { | ||
742 | + if (!isFourOctetCapabilityExits) { | ||
743 | + tempTlv = new FourOctetAsNumCapabilityTlv(h.bgpconfig.getAsNumber()); | ||
744 | + unSupportedCapabilityTlv.add(tempTlv); | ||
745 | + } | ||
746 | + } | ||
747 | + | ||
748 | + if (unSupportedCaplistIterator.hasNext()) { | ||
749 | + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); | ||
750 | + while (unSupportedCaplistIterator.hasNext()) { | ||
751 | + BGPValueType tlv = unSupportedCaplistIterator.next(); | ||
752 | + tlv.write(buffer); | ||
753 | + } | ||
754 | + throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, | ||
755 | + BGPErrorType.UNSUPPORTED_CAPABILITY, buffer); | ||
756 | + } else { | ||
757 | + return true; | ||
758 | + } | ||
759 | + } | ||
760 | + | ||
761 | + /** | ||
762 | + * AS Number Validation. | ||
763 | + * | ||
764 | + * @param h channel Handler | ||
765 | + * @param openMsg open message | ||
766 | + * @return true or false | ||
767 | + */ | ||
768 | + private boolean asNumberValidation(BGPChannelHandler h, BGPOpenMsg openMsg) { | ||
769 | + log.debug("AS Num validation"); | ||
770 | + | ||
771 | + int capAsNum = 0; | ||
772 | + boolean isFourOctetCapabilityExits = false; | ||
773 | + | ||
774 | + BGPPeerCfg peerCfg = h.bgpconfig.displayPeers(peerAddr); | ||
775 | + List<BGPValueType> capabilityTlv = openMsg.getCapabilityTlv(); | ||
776 | + ListIterator<BGPValueType> listIterator = capabilityTlv.listIterator(); | ||
777 | + | ||
778 | + while (listIterator.hasNext()) { | ||
779 | + BGPValueType tlv = listIterator.next(); | ||
780 | + if (tlv.getType() == FOUR_OCTET_AS_NUM_CAPA_TYPE) { | ||
781 | + isFourOctetCapabilityExits = true; | ||
782 | + capAsNum = ((FourOctetAsNumCapabilityTlv) tlv).getInt(); | ||
783 | + } | ||
784 | + } | ||
785 | + | ||
786 | + if (peerCfg.getAsNumber() > MAX_AS2_NUM) { | ||
787 | + if (openMsg.getAsNumber() != AS_TRANS) { | ||
788 | + return false; | ||
789 | + } | ||
790 | + | ||
791 | + if (!isFourOctetCapabilityExits) { | ||
792 | + return false; | ||
793 | + } | ||
794 | + | ||
795 | + if (peerCfg.getAsNumber() != capAsNum) { | ||
796 | + return false; | ||
797 | + } | ||
798 | + | ||
799 | + isIbgpSession = peerCfg.getIsIBgp(); | ||
800 | + if (isIbgpSession) { | ||
801 | + // IBGP - AS number should be same for Peer and local if it is IBGP | ||
802 | + if (h.bgpconfig.getAsNumber() != capAsNum) { | ||
803 | + return false; | ||
804 | + } | ||
805 | + } | ||
806 | + } else { | ||
807 | + | ||
808 | + if (openMsg.getAsNumber() != peerCfg.getAsNumber()) { | ||
809 | + return false; | ||
810 | + } | ||
811 | + | ||
812 | + if (isFourOctetCapabilityExits) { | ||
813 | + if (capAsNum != peerCfg.getAsNumber()) { | ||
814 | + return false; | ||
815 | + } | ||
816 | + } | ||
817 | + | ||
818 | + isIbgpSession = peerCfg.getIsIBgp(); | ||
819 | + if (isIbgpSession) { | ||
820 | + // IBGP - AS number should be same for Peer and local if it is IBGP | ||
821 | + if (openMsg.getAsNumber() != h.bgpconfig.getAsNumber()) { | ||
822 | + return false; | ||
823 | + } | ||
824 | + } | ||
825 | + } | ||
826 | + return true; | ||
827 | + } | ||
828 | + | ||
829 | + /** | ||
830 | + * Validates BGP ID. | ||
831 | + * | ||
832 | + * @param openMsg open message | ||
833 | + * @return true or false | ||
645 | */ | 834 | */ |
646 | - public boolean openMsgValidation(BGPChannelHandler h, BGPOpenMsg pOpenmsg) throws BGPParseException { | 835 | + private boolean bgpIdValidation(BGPOpenMsg openMsg) { |
647 | - // TODO: Open message validation. | 836 | + String openMsgBgpId = Ip4Address.valueOf(openMsg.getBgpId()).toString(); |
837 | + | ||
838 | + InetAddress ipAddress; | ||
839 | + try { | ||
840 | + ipAddress = InetAddress.getByName(openMsgBgpId); | ||
841 | + if (ipAddress.isMulticastAddress()) { | ||
842 | + return false; | ||
843 | + } | ||
844 | + } catch (UnknownHostException e) { | ||
845 | + log.debug("InetAddress convertion failed"); | ||
846 | + } | ||
648 | return true; | 847 | return true; |
649 | } | 848 | } |
650 | } | 849 | } | ... | ... |
-
Please register or login to post a comment