8454a2b9126d4c821b0070c81a38c5ccd8539528
[vtn.git] /
1 /*
2  * Copyright (c) 2014, 2015 NEC Corporation.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.vtn.manager.internal.packet.cache;
10
11 import org.opendaylight.vtn.manager.VTNException;
12
13 import org.opendaylight.vtn.manager.internal.util.MiscUtils;
14 import org.opendaylight.vtn.manager.internal.util.flow.match.FlowMatchType;
15 import org.opendaylight.vtn.manager.internal.util.flow.match.VTNPortRange;
16 import org.opendaylight.vtn.manager.internal.util.flow.match.VTNUdpMatch;
17 import org.opendaylight.vtn.manager.internal.util.packet.UdpHeader;
18
19 import org.opendaylight.controller.sal.packet.UDP;
20
21 /**
22  * {@code UdpPacket} class implements a cache for a {@link UDP} instance.
23  */
24 public final class UdpPacket extends PortProtoPacket<UDP>
25     implements UdpHeader {
26     /**
27      * Byte offset to the checksum field in UDP header.
28      */
29     private static final int  UDP_OFF_CHECKSUM = 6;
30
31     /**
32      * Checksum value which indicates the checksum is disabled.
33      */
34     private static final short  UDP_CKSUM_DISABLED = 0;
35
36     /**
37      * A {@link UDP} packet.
38      */
39     private UDP  packet;
40
41     /**
42      * Construct a new instance.
43      *
44      * @param udp  A {@link UDP} instance.
45      */
46     public UdpPacket(UDP udp) {
47         packet = udp;
48     }
49
50     /**
51      * Derive the source port number from the packet.
52      *
53      * @return  A short integer value which represents the source port number.
54      */
55     @Override
56     protected short getRawSourcePort() {
57         return packet.getSourcePort();
58     }
59
60     /**
61      * Derive the destination port number from the packet.
62      *
63      * @return  A short integer value which represents the destination port
64      *          number.
65      */
66     @Override
67     protected short getRawDestinationPort() {
68         return packet.getDestinationPort();
69     }
70
71     /**
72      * Set the source port number to the given packet.
73      *
74      * @param pkt   A {@link UDP} instance.
75      * @param port  A short integer value which indicates the source port.
76      */
77     @Override
78     protected void setRawSourcePort(UDP pkt, short port) {
79         pkt.setSourcePort(port);
80     }
81
82     /**
83      * Set the destination port number to the given packet.
84      *
85      * @param pkt   A {@link UDP} instance.
86      * @param port  A short integer value which indicates the destination port.
87      */
88     @Override
89     protected void setRawDestinationPort(UDP pkt, short port) {
90         pkt.setDestinationPort(port);
91     }
92
93     /**
94      * Return a {@link UDP} instance to set modified values.
95      *
96      * @param doCopy {@code true} is passed if the packet configured in this
97      *               instance needs to be copied.
98      * @return  A {@link UDP} instance.
99      * @throws VTNException
100      *    Failed to copy the packet.
101      */
102     @Override
103     protected UDP getPacketForWrite(boolean doCopy) throws VTNException {
104         UDP pkt;
105         if (doCopy) {
106             pkt = MiscUtils.copy(packet, new UDP());
107             packet = pkt;
108         } else {
109             pkt = packet;
110         }
111
112         return pkt;
113     }
114
115     /**
116      * Return the name of the protocol.
117      *
118      * @return  {@code "UDP"}.
119      */
120     @Override
121     protected String getProtocolName() {
122         return "UDP";
123     }
124
125     /**
126      * Construct UDP flow match fields.
127      *
128      * @param src  A {@link VTNPortRange} instance which specifies the
129      *             source port.
130      * @param dst  A {@link VTNPortRange} instance which specifies the
131      *             destination port.
132      * @return  A {@link VTNUdpMatch} instance.
133      */
134     @Override
135     protected VTNUdpMatch createMatch(VTNPortRange src, VTNPortRange dst) {
136         return new VTNUdpMatch(src, dst);
137     }
138
139     /**
140      * Return a flow match type corresponding to the source port.
141      *
142      * @return  {@link FlowMatchType#UDP_SRC}.
143      */
144     @Override
145     public FlowMatchType getSourceMatchType() {
146         return FlowMatchType.UDP_SRC;
147     }
148
149     /**
150      * Return a flow match type corresponding to the destination port.
151      *
152      * @return  {@link FlowMatchType#UDP_DST}.
153      */
154     @Override
155     public FlowMatchType getDestinationMatchType() {
156         return FlowMatchType.UDP_DST;
157     }
158
159     // L4Packet
160
161     /**
162      * {@inheritDoc}
163      */
164     @Override
165     public boolean updateChecksum(Inet4Packet ipv4) throws VTNException {
166         // Update checksum only if the UDP packet contains a valid checksum.
167         boolean mod = false;
168         short sum = packet.getChecksum();
169         if (sum != 0) {
170             UDP pkt = getPacketForWrite();
171             short newSum = computeChecksum(ipv4, pkt, UDP_OFF_CHECKSUM);
172             if (newSum == UDP_CKSUM_DISABLED) {
173                 // Set all bits in the checksum field instead of zero.
174                 newSum = (short)~newSum;
175             }
176             if (sum != newSum) {
177                 pkt.setChecksum(newSum);
178                 mod = true;
179             }
180         }
181
182         return mod;
183     }
184
185     // CachedPacket
186
187     /**
188      * Return a {@link UDP} instance configured in this instance.
189      *
190      * @return  A {@link UDP} instance.
191      */
192     @Override
193     public UDP getPacket() {
194         return packet;
195     }
196 }