X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fsal%2Fapi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fpacket%2FIPv4.java;h=56793c41f6ef624efedd743b9682bb13bede8018;hb=4aac6809c89d1a58d1d7ab9aa4af528cc9d8bb3e;hp=1e2f4277c1f4035b873c61502a43bdc1e6d6fe4c;hpb=a9e6627736e99183c5c6be4dd42ec364836acb80;p=controller.git diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPv4.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPv4.java index 1e2f4277c1..56793c41f6 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPv4.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPv4.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2013-2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, @@ -20,6 +20,8 @@ import java.util.Random; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; +import org.opendaylight.controller.sal.match.Match; +import org.opendaylight.controller.sal.match.MatchType; import org.opendaylight.controller.sal.utils.IPProtocols; import org.opendaylight.controller.sal.utils.NetUtils; import org.slf4j.Logger; @@ -47,6 +49,10 @@ public class IPv4 extends Packet { private static final String DIP = "DestinationIPAddress"; private static final String OPTIONS = "Options"; + private static final int UNIT_SIZE_SHIFT = 2; + private static final int UNIT_SIZE = (1 << UNIT_SIZE_SHIFT); + private static final int MIN_HEADER_SIZE = 20; + public static final Map> protocolClassMap; static { protocolClassMap = new HashMap>(); @@ -145,12 +151,7 @@ public class IPv4 extends Packet { public int getHeaderSize() { int headerLen = this.getHeaderLen(); if (headerLen == 0) { - headerLen = 20; - } - - byte[] options = hdrFieldsMap.get(OPTIONS); - if (options != null) { - headerLen += options.length; + headerLen = MIN_HEADER_SIZE; } return headerLen * NetUtils.NumBitsInAByte; @@ -259,7 +260,21 @@ public class IPv4 extends Packet { */ public void setHeaderField(String headerField, byte[] readValue) { if (headerField.equals(PROTOCOL)) { - payloadClass = protocolClassMap.get(readValue[0]); + // Don't set payloadClass if framgment offset is not zero. + byte[] fragoff = hdrFieldsMap.get(FRAGOFFSET); + if (fragoff == null || BitBufferHelper.getShort(fragoff) == 0) { + payloadClass = protocolClassMap.get(readValue[0]); + } + } else if (headerField.equals(FRAGOFFSET)) { + if (readValue != null && BitBufferHelper.getShort(readValue) != 0) { + // Clear payloadClass because protocol header is not present + // in this packet. + payloadClass = null; + } + } else if (headerField.equals(OPTIONS) && + (readValue == null || readValue.length == 0)) { + hdrFieldsMap.remove(headerField); + return; } hdrFieldsMap.put(headerField, readValue); } @@ -276,7 +291,7 @@ public class IPv4 extends Packet { } /** - * Stores the length of IP header in words (2 bytes) + * Stores the length of IP header in words (4 bytes) * @param headerLength the headerLength to set * @return IPv4 */ @@ -434,8 +449,23 @@ public class IPv4 extends Packet { * @return IPv4 */ public IPv4 setOptions(byte[] options) { - fieldValues.put(OPTIONS, options); - byte newIHL = (byte) (5 + options.length); + byte newIHL = (byte)(MIN_HEADER_SIZE >>> UNIT_SIZE_SHIFT); + if (options == null || options.length == 0) { + fieldValues.remove(OPTIONS); + } else { + int len = options.length; + int rlen = (len + (UNIT_SIZE - 1)) & ~(UNIT_SIZE - 1); + if (rlen > len) { + // Padding is required. + byte[] newopt = new byte[rlen]; + System.arraycopy(options, 0, newopt, 0, len); + options = newopt; + len = rlen; + } + fieldValues.put(OPTIONS, options); + newIHL += (len >>> UNIT_SIZE_SHIFT); + } + setHeaderLength(newIHL); return this; @@ -477,15 +507,13 @@ public class IPv4 extends Packet { @Override /** * Gets the number of bits for the fieldname specified - * If the fieldname has variable length like "Options", then this value is computed using the - * options length and the header length + * If the fieldname has variable length like "Options", then this value is computed using the header length * @param fieldname - String * @return number of bits for fieldname - int */ public int getfieldnumBits(String fieldName) { if (fieldName.equals(OPTIONS)) { - byte[] options = getOptions(); - return ((options == null) ? 0 : (options.length - getHeaderLen())); + return (getHeaderLen() - MIN_HEADER_SIZE) * NetUtils.NumBitsInAByte; } return hdrFieldCoordMap.get(fieldName).getRight(); } @@ -561,4 +589,12 @@ public class IPv4 extends Packet { corrupted = true; } } + + @Override + public void populateMatch(Match match) { + match.setField(MatchType.NW_SRC, NetUtils.getInetAddress(this.getSourceAddress())); + match.setField(MatchType.NW_DST, NetUtils.getInetAddress(this.getDestinationAddress())); + match.setField(MatchType.NW_PROTO, this.getProtocol()); + match.setField(MatchType.NW_TOS, this.getDiffServ()); + } }