Conflicts: include/linux/blkdev.h Trivial merge to incorporate tag prototypes.
Unified · Split
| @@ -2384,6 +2384,13 @@ N: Thomas Molina · 2383 unmodified lines | |||
| 2384 | E: tmolina@cablespeed.com | 2384 | E: tmolina@cablespeed.com |
| 2385 | D: bug fixes, documentation, minor hackery | 2385 | D: bug fixes, documentation, minor hackery |
| 2386 | 2386 | ||
| 2387 | N: Paul Moore | ||
| 2388 | E: paul.moore@hp.com | ||
| 2389 | D: NetLabel author | ||
| 2390 | S: Hewlett-Packard | ||
| 2391 | S: 110 Spit Brook Road | ||
| 2392 | S: Nashua, NH 03062 | ||
| 2393 | |||
| 2387 | N: James Morris | 2394 | N: James Morris |
| 2388 | E: jmorris@namei.org | 2395 | E: jmorris@namei.org |
| 2389 | W: http://namei.org/ | 2396 | W: http://namei.org/ |
| @@ -184,6 +184,8 @@ mtrr.txt · 183 unmodified lines | |||
| 184 | - how to use PPro Memory Type Range Registers to increase performance. | 184 | - how to use PPro Memory Type Range Registers to increase performance. |
| 185 | nbd.txt | 185 | nbd.txt |
| 186 | - info on a TCP implementation of a network block device. | 186 | - info on a TCP implementation of a network block device. |
| 187 | netlabel/ | ||
| 188 | - directory with information on the NetLabel subsystem. | ||
| 187 | networking/ | 189 | networking/ |
| 188 | - directory with info on various aspects of networking with Linux. | 190 | - directory with info on various aspects of networking with Linux. |
| 189 | nfsroot.txt | 191 | nfsroot.txt |
| @@ -0,0 +1,10 @@ | |||
| 1 | 00-INDEX | ||
| 2 | - this file. | ||
| 3 | cipso_ipv4.txt | ||
| 4 | - documentation on the IPv4 CIPSO protocol engine. | ||
| 5 | draft-ietf-cipso-ipsecurity-01.txt | ||
| 6 | - IETF draft of the CIPSO protocol, dated 16 July 1992. | ||
| 7 | introduction.txt | ||
| 8 | - NetLabel introduction, READ THIS FIRST. | ||
| 9 | lsm_interface.txt | ||
| 10 | - documentation on the NetLabel kernel security module API. | ||
| @@ -0,0 +1,48 @@ | |||
| 1 | NetLabel CIPSO/IPv4 Protocol Engine | ||
| 2 | ============================================================================== | ||
| 3 | Paul Moore, paul.moore@hp.com | ||
| 4 | |||
| 5 | May 17, 2006 | ||
| 6 | |||
| 7 | * Overview | ||
| 8 | |||
| 9 | The NetLabel CIPSO/IPv4 protocol engine is based on the IETF Commercial IP | ||
| 10 | Security Option (CIPSO) draft from July 16, 1992. A copy of this draft can be | ||
| 11 | found in this directory, consult '00-INDEX' for the filename. While the IETF | ||
| 12 | draft never made it to an RFC standard it has become a de-facto standard for | ||
| 13 | labeled networking and is used in many trusted operating systems. | ||
| 14 | |||
| 15 | * Outbound Packet Processing | ||
| 16 | |||
| 17 | The CIPSO/IPv4 protocol engine applies the CIPSO IP option to packets by | ||
| 18 | adding the CIPSO label to the socket. This causes all packets leaving the | ||
| 19 | system through the socket to have the CIPSO IP option applied. The socket's | ||
| 20 | CIPSO label can be changed at any point in time, however, it is recommended | ||
| 21 | that it is set upon the socket's creation. The LSM can set the socket's CIPSO | ||
| 22 | label by using the NetLabel security module API; if the NetLabel "domain" is | ||
| 23 | configured to use CIPSO for packet labeling then a CIPSO IP option will be | ||
| 24 | generated and attached to the socket. | ||
| 25 | |||
| 26 | * Inbound Packet Processing | ||
| 27 | |||
| 28 | The CIPSO/IPv4 protocol engine validates every CIPSO IP option it finds at the | ||
| 29 | IP layer without any special handling required by the LSM. However, in order | ||
| 30 | to decode and translate the CIPSO label on the packet the LSM must use the | ||
| 31 | NetLabel security module API to extract the security attributes of the packet. | ||
| 32 | This is typically done at the socket layer using the 'socket_sock_rcv_skb()' | ||
| 33 | LSM hook. | ||
| 34 | |||
| 35 | * Label Translation | ||
| 36 | |||
| 37 | The CIPSO/IPv4 protocol engine contains a mechanism to translate CIPSO security | ||
| 38 | attributes such as sensitivity level and category to values which are | ||
| 39 | appropriate for the host. These mappings are defined as part of a CIPSO | ||
| 40 | Domain Of Interpretation (DOI) definition and are configured through the | ||
| 41 | NetLabel user space communication layer. Each DOI definition can have a | ||
| 42 | different security attribute mapping table. | ||
| 43 | |||
| 44 | * Label Translation Cache | ||
| 45 | |||
| 46 | The NetLabel system provides a framework for caching security attribute | ||
| 47 | mappings from the network labels to the corresponding LSM identifiers. The | ||
| 48 | CIPSO/IPv4 protocol engine supports this caching mechanism. | ||
| @@ -0,0 +1,791 @@ | |||
| 1 | IETF CIPSO Working Group | ||
| 2 | 16 July, 1992 | ||
| 3 | |||
| 4 | |||
| 5 | |||
| 6 | COMMERCIAL IP SECURITY OPTION (CIPSO 2.2) | ||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | 1. Status | ||
| 11 | |||
| 12 | This Internet Draft provides the high level specification for a Commercial | ||
| 13 | IP Security Option (CIPSO). This draft reflects the version as approved by | ||
| 14 | the CIPSO IETF Working Group. Distribution of this memo is unlimited. | ||
| 15 | |||
| 16 | This document is an Internet Draft. Internet Drafts are working documents | ||
| 17 | of the Internet Engineering Task Force (IETF), its Areas, and its Working | ||
| 18 | Groups. Note that other groups may also distribute working documents as | ||
| 19 | Internet Drafts. | ||
| 20 | |||
| 21 | Internet Drafts are draft documents valid for a maximum of six months. | ||
| 22 | Internet Drafts may be updated, replaced, or obsoleted by other documents | ||
| 23 | at any time. It is not appropriate to use Internet Drafts as reference | ||
| 24 | material or to cite them other than as a "working draft" or "work in | ||
| 25 | progress." | ||
| 26 | |||
| 27 | Please check the I-D abstract listing contained in each Internet Draft | ||
| 28 | directory to learn the current status of this or any other Internet Draft. | ||
| 29 | |||
| 30 | |||
| 31 | |||
| 32 | |||
| 33 | 2. Background | ||
| 34 | |||
| 35 | Currently the Internet Protocol includes two security options. One of | ||
| 36 | these options is the DoD Basic Security Option (BSO) (Type 130) which allows | ||
| 37 | IP datagrams to be labeled with security classifications. This option | ||
| 38 | provides sixteen security classifications and a variable number of handling | ||
| 39 | restrictions. To handle additional security information, such as security | ||
| 40 | categories or compartments, another security option (Type 133) exists and | ||
| 41 | is referred to as the DoD Extended Security Option (ESO). The values for | ||
| 42 | the fixed fields within these two options are administered by the Defense | ||
| 43 | Information Systems Agency (DISA). | ||
| 44 | |||
| 45 | Computer vendors are now building commercial operating systems with | ||
| 46 | mandatory access controls and multi-level security. These systems are | ||
| 47 | no longer built specifically for a particular group in the defense or | ||
| 48 | intelligence communities. They are generally available commercial systems | ||
| 49 | for use in a variety of government and civil sector environments. | ||
| 50 | |||
| 51 | The small number of ESO format codes can not support all the possible | ||
| 52 | applications of a commercial security option. The BSO and ESO were | ||
| 53 | designed to only support the United States DoD. CIPSO has been designed | ||
| 54 | to support multiple security policies. This Internet Draft provides the | ||
| 55 | format and procedures required to support a Mandatory Access Control | ||
| 56 | security policy. Support for additional security policies shall be | ||
| 57 | defined in future RFCs. | ||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | Internet Draft, Expires 15 Jan 93 [PAGE 1] | ||
| 63 | |||
| 64 | |||
| 65 | |||
| 66 | CIPSO INTERNET DRAFT 16 July, 1992 | ||
| 67 | |||
| 68 | |||
| 69 | |||
| 70 | |||
| 71 | 3. CIPSO Format | ||
| 72 | |||
| 73 | Option type: 134 (Class 0, Number 6, Copy on Fragmentation) | ||
| 74 | Option length: Variable | ||
| 75 | |||
| 76 | This option permits security related information to be passed between | ||
| 77 | systems within a single Domain of Interpretation (DOI). A DOI is a | ||
| 78 | collection of systems which agree on the meaning of particular values | ||
| 79 | in the security option. An authority that has been assigned a DOI | ||
| 80 | identifier will define a mapping between appropriate CIPSO field values | ||
| 81 | and their human readable equivalent. This authority will distribute that | ||
| 82 | mapping to hosts within the authority's domain. These mappings may be | ||
| 83 | sensitive, therefore a DOI authority is not required to make these | ||
| 84 | mappings available to anyone other than the systems that are included in | ||
| 85 | the DOI. | ||
| 86 | |||
| 87 | This option MUST be copied on fragmentation. This option appears at most | ||
| 88 | once in a datagram. All multi-octet fields in the option are defined to be | ||
| 89 | transmitted in network byte order. The format of this option is as follows: | ||
| 90 | |||
| 91 | +----------+----------+------//------+-----------//---------+ | ||
| 92 | | 10000110 | LLLLLLLL | DDDDDDDDDDDD | TTTTTTTTTTTTTTTTTTTT | | ||
| 93 | +----------+----------+------//------+-----------//---------+ | ||
| 94 | |||
| 95 | TYPE=134 OPTION DOMAIN OF TAGS | ||
| 96 | LENGTH INTERPRETATION | ||
| 97 | |||
| 98 | |||
| 99 | Figure 1. CIPSO Format | ||
| 100 | |||
| 101 | |||
| 102 | 3.1 Type | ||
| 103 | |||
| 104 | This field is 1 octet in length. Its value is 134. | ||
| 105 | |||
| 106 | |||
| 107 | 3.2 Length | ||
| 108 | |||
| 109 | This field is 1 octet in length. It is the total length of the option | ||
| 110 | including the type and length fields. With the current IP header length | ||
| 111 | restriction of 40 octets the value of this field MUST not exceed 40. | ||
| 112 | |||
| 113 | |||
| 114 | 3.3 Domain of Interpretation Identifier | ||
| 115 | |||
| 116 | This field is an unsigned 32 bit integer. The value 0 is reserved and MUST | ||
| 117 | not appear as the DOI identifier in any CIPSO option. Implementations | ||
| 118 | should assume that the DOI identifier field is not aligned on any particular | ||
| 119 | byte boundary. | ||
| 120 | |||
| 121 | To conserve space in the protocol, security levels and categories are | ||
| 122 | represented by numbers rather than their ASCII equivalent. This requires | ||
| 123 | a mapping table within CIPSO hosts to map these numbers to their | ||
| 124 | corresponding ASCII representations. Non-related groups of systems may | ||
| 125 | |||
| 126 | |||
| 127 | |||
| 128 | Internet Draft, Expires 15 Jan 93 [PAGE 2] | ||
| 129 | |||
| 130 | |||
| 131 | |||
| 132 | CIPSO INTERNET DRAFT 16 July, 1992 | ||
| 133 | |||
| 134 | |||
| 135 | |||
| 136 | have their own unique mappings. For example, one group of systems may | ||
| 137 | use the number 5 to represent Unclassified while another group may use the | ||
| 138 | number 1 to represent that same security level. The DOI identifier is used | ||
| 139 | to identify which mapping was used for the values within the option. | ||
| 140 | |||
| 141 | |||
| 142 | 3.4 Tag Types | ||
| 143 | |||
| 144 | A common format for passing security related information is necessary | ||
| 145 | for interoperability. CIPSO uses sets of "tags" to contain the security | ||
| 146 | information relevant to the data in the IP packet. Each tag begins with | ||
| 147 | a tag type identifier followed by the length of the tag and ends with the | ||
| 148 | actual security information to be passed. All multi-octet fields in a tag | ||
| 149 | are defined to be transmitted in network byte order. Like the DOI | ||
| 150 | identifier field in the CIPSO header, implementations should assume that | ||
| 151 | all tags, as well as fields within a tag, are not aligned on any particular | ||
| 152 | octet boundary. The tag types defined in this document contain alignment | ||
| 153 | bytes to assist alignment of some information, however alignment can not | ||
| 154 | be guaranteed if CIPSO is not the first IP option. | ||
| 155 | |||
| 156 | CIPSO tag types 0 through 127 are reserved for defining standard tag | ||
| 157 | formats. Their definitions will be published in RFCs. Tag types whose | ||
| 158 | identifiers are greater than 127 are defined by the DOI authority and may | ||
| 159 | only be meaningful in certain Domains of Interpretation. For these tag | ||
| 160 | types, implementations will require the DOI identifier as well as the tag | ||
| 161 | number to determine the security policy and the format associated with the | ||
| 162 | tag. Use of tag types above 127 are restricted to closed networks where | ||
| 163 | interoperability with other networks will not be an issue. Implementations | ||
| 164 | that support a tag type greater than 127 MUST support at least one DOI that | ||
| 165 | requires only tag types 1 to 127. | ||
| 166 | |||
| 167 | Tag type 0 is reserved. Tag types 1, 2, and 5 are defined in this | ||
| 168 | Internet Draft. Types 3 and 4 are reserved for work in progress. | ||
| 169 | The standard format for all current and future CIPSO tags is shown below: | ||
| 170 | |||
| 171 | +----------+----------+--------//--------+ | ||
| 172 | | TTTTTTTT | LLLLLLLL | IIIIIIIIIIIIIIII | | ||
| 173 | +----------+----------+--------//--------+ | ||
| 174 | TAG TAG TAG | ||
| 175 | TYPE LENGTH INFORMATION | ||
| 176 | |||
| 177 | Figure 2: Standard Tag Format | ||
| 178 | |||
| 179 | In the three tag types described in this document, the length and count | ||
| 180 | restrictions are based on the current IP limitation of 40 octets for all | ||
| 181 | IP options. If the IP header is later expanded, then the length and count | ||
| 182 | restrictions specified in this document may increase to use the full area | ||
| 183 | provided for IP options. | ||
| 184 | |||
| 185 | |||
| 186 | 3.4.1 Tag Type Classes | ||
| 187 | |||
| 188 | Tag classes consist of tag types that have common processing requirements | ||
| 189 | and support the same security policy. The three tags defined in this | ||
| 190 | Internet Draft belong to the Mandatory Access Control (MAC) Sensitivity | ||
| 191 | |||
| 192 | |||
| 193 | |||
| 194 | Internet Draft, Expires 15 Jan 93 [PAGE 3] | ||
| 195 | |||
| 196 | |||
| 197 | |||
| 198 | CIPSO INTERNET DRAFT 16 July, 1992 | ||
| 199 | |||
| 200 | |||
| 201 | |||
| 202 | class and support the MAC Sensitivity security policy. | ||
| 203 | |||
| 204 | |||
| 205 | 3.4.2 Tag Type 1 | ||
| 206 | |||
| 207 | This is referred to as the "bit-mapped" tag type. Tag type 1 is included | ||
| 208 | in the MAC Sensitivity tag type class. The format of this tag type is as | ||
| 209 | follows: | ||
| 210 | |||
| 211 | +----------+----------+----------+----------+--------//---------+ | ||
| 212 | | 00000001 | LLLLLLLL | 00000000 | LLLLLLLL | CCCCCCCCCCCCCCCCC | | ||
| 213 | +----------+----------+----------+----------+--------//---------+ | ||
| 214 | |||
| 215 | TAG TAG ALIGNMENT SENSITIVITY BIT MAP OF | ||
| 216 | TYPE LENGTH OCTET LEVEL CATEGORIES | ||
| 217 | |||
| 218 | Figure 3. Tag Type 1 Format | ||
| 219 | |||
| 220 | |||
| 221 | 3.4.2.1 Tag Type | ||
| 222 | |||
| 223 | This field is 1 octet in length and has a value of 1. | ||
| 224 | |||
| 225 | |||
| 226 | 3.4.2.2 Tag Length | ||
| 227 | |||
| 228 | This field is 1 octet in length. It is the total length of the tag type | ||
| 229 | including the type and length fields. With the current IP header length | ||
| 230 | restriction of 40 bytes the value within this field is between 4 and 34. | ||
| 231 | |||
| 232 | |||
| 233 | 3.4.2.3 Alignment Octet | ||
| 234 | |||
| 235 | This field is 1 octet in length and always has the value of 0. Its purpose | ||
| 236 | is to align the category bitmap field on an even octet boundary. This will | ||
| 237 | speed many implementations including router implementations. | ||
| 238 | |||
| 239 | |||
| 240 | 3.4.2.4 Sensitivity Level | ||
| 241 | |||
| 242 | This field is 1 octet in length. Its value is from 0 to 255. The values | ||
| 243 | are ordered with 0 being the minimum value and 255 representing the maximum | ||
| 244 | value. | ||
| 245 | |||
| 246 | |||
| 247 | 3.4.2.5 Bit Map of Categories | ||
| 248 | |||
| 249 | The length of this field is variable and ranges from 0 to 30 octets. This | ||
| 250 | provides representation of categories 0 to 239. The ordering of the bits | ||
| 251 | is left to right or MSB to LSB. For example category 0 is represented by | ||
| 252 | the most significant bit of the first byte and category 15 is represented | ||
| 253 | by the least significant bit of the second byte. Figure 4 graphically | ||
| 254 | shows this ordering. Bit N is binary 1 if category N is part of the label | ||
| 255 | for the datagram, and bit N is binary 0 if category N is not part of the | ||
| 256 | label. Except for the optimized tag 1 format described in the next section, | ||
| 257 | |||
| 258 | |||
| 259 | |||
| 260 | Internet Draft, Expires 15 Jan 93 [PAGE 4] | ||
| 261 | |||
| 262 | |||
| 263 | |||
| 264 | CIPSO INTERNET DRAFT 16 July, 1992 | ||
| 265 | |||
| 266 | |||
| 267 | |||
| 268 | minimal encoding SHOULD be used resulting in no trailing zero octets in the | ||
| 269 | category bitmap. | ||
| 270 | |||
| 271 | octet 0 octet 1 octet 2 octet 3 octet 4 octet 5 | ||
| 272 | XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX . . . | ||
| 273 | bit 01234567 89111111 11112222 22222233 33333333 44444444 | ||
| 274 | number 012345 67890123 45678901 23456789 01234567 | ||
| 275 | |||
| 276 | Figure 4. Ordering of Bits in Tag 1 Bit Map | ||
| 277 | |||
| 278 | |||
| 279 | 3.4.2.6 Optimized Tag 1 Format | ||
| 280 | |||
| 281 | Routers work most efficiently when processing fixed length fields. To | ||
| 282 | support these routers there is an optimized form of tag type 1. The format | ||
| 283 | does not change. The only change is to the category bitmap which is set to | ||
| 284 | a constant length of 10 octets. Trailing octets required to fill out the 10 | ||
| 285 | octets are zero filled. Ten octets, allowing for 80 categories, was chosen | ||
| 286 | because it makes the total length of the CIPSO option 20 octets. If CIPSO | ||
| 287 | is the only option then the option will be full word aligned and additional | ||
| 288 | filler octets will not be required. | ||
| 289 | |||
| 290 | |||
| 291 | 3.4.3 Tag Type 2 | ||
| 292 | |||
| 293 | This is referred to as the "enumerated" tag type. It is used to describe | ||
| 294 | large but sparsely populated sets of categories. Tag type 2 is in the MAC | ||
| 295 | Sensitivity tag type class. The format of this tag type is as follows: | ||
| 296 | |||
| 297 | +----------+----------+----------+----------+-------------//-------------+ | ||
| 298 | | 00000010 | LLLLLLLL | 00000000 | LLLLLLLL | CCCCCCCCCCCCCCCCCCCCCCCCCC | | ||
| 299 | +----------+----------+----------+----------+-------------//-------------+ | ||
| 300 | |||
| 301 | TAG TAG ALIGNMENT SENSITIVITY ENUMERATED | ||
| 302 | TYPE LENGTH OCTET LEVEL CATEGORIES | ||
| 303 | |||
| 304 | Figure 5. Tag Type 2 Format | ||
| 305 | |||
| 306 | |||
| 307 | 3.4.3.1 Tag Type | ||
| 308 | |||
| 309 | This field is one octet in length and has a value of 2. | ||
| 310 | |||
| 311 | |||
| 312 | 3.4.3.2 Tag Length | ||
| 313 | |||
| 314 | This field is 1 octet in length. It is the total length of the tag type | ||
| 315 | including the type and length fields. With the current IP header length | ||
| 316 | restriction of 40 bytes the value within this field is between 4 and 34. | ||
| 317 | |||
| 318 | |||
| 319 | 3.4.3.3 Alignment Octet | ||
| 320 | |||
| 321 | This field is 1 octet in length and always has the value of 0. Its purpose | ||
| 322 | is to align the category field on an even octet boundary. This will | ||
| 323 | |||
| 324 | |||
| 325 | |||
| 326 | Internet Draft, Expires 15 Jan 93 [PAGE 5] | ||
| 327 | |||
| 328 | |||
| 329 | |||
| 330 | CIPSO INTERNET DRAFT 16 July, 1992 | ||
| 331 | |||
| 332 | |||
| 333 | |||
| 334 | speed many implementations including router implementations. | ||
| 335 | |||
| 336 | |||
| 337 | 3.4.3.4 Sensitivity Level | ||
| 338 | |||
| 339 | This field is 1 octet in length. Its value is from 0 to 255. The values | ||
| 340 | are ordered with 0 being the minimum value and 255 representing the | ||
| 341 | maximum value. | ||
| 342 | |||
| 343 | |||
| 344 | 3.4.3.5 Enumerated Categories | ||
| 345 | |||
| 346 | In this tag, categories are represented by their actual value rather than | ||
| 347 | by their position within a bit field. The length of each category is 2 | ||
| 348 | octets. Up to 15 categories may be represented by this tag. Valid values | ||
| 349 | for categories are 0 to 65534. Category 65535 is not a valid category | ||
| 350 | value. The categories MUST be listed in ascending order within the tag. | ||
| 351 | |||
| 352 | |||
| 353 | 3.4.4 Tag Type 5 | ||
| 354 | |||
| 355 | This is referred to as the "range" tag type. It is used to represent | ||
| 356 | labels where all categories in a range, or set of ranges, are included | ||
| 357 | in the sensitivity label. Tag type 5 is in the MAC Sensitivity tag type | ||
| 358 | class. The format of this tag type is as follows: | ||
| 359 | |||
| 360 | +----------+----------+----------+----------+------------//-------------+ | ||
| 361 | | 00000101 | LLLLLLLL | 00000000 | LLLLLLLL | Top/Bottom | Top/Bottom | | ||
| 362 | +----------+----------+----------+----------+------------//-------------+ | ||
| 363 | |||
| 364 | TAG TAG ALIGNMENT SENSITIVITY CATEGORY RANGES | ||
| 365 | TYPE LENGTH OCTET LEVEL | ||
| 366 | |||
| 367 | Figure 6. Tag Type 5 Format | ||
| 368 | |||
| 369 | |||
| 370 | 3.4.4.1 Tag Type | ||
| 371 | |||
| 372 | This field is one octet in length and has a value of 5. | ||
| 373 | |||
| 374 | |||
| 375 | 3.4.4.2 Tag Length | ||
| 376 | |||
| 377 | This field is 1 octet in length. It is the total length of the tag type | ||
| 378 | including the type and length fields. With the current IP header length | ||
| 379 | restriction of 40 bytes the value within this field is between 4 and 34. | ||
| 380 | |||
| 381 | |||
| 382 | 3.4.4.3 Alignment Octet | ||
| 383 | |||
| 384 | This field is 1 octet in length and always has the value of 0. Its purpose | ||
| 385 | is to align the category range field on an even octet boundary. This will | ||
| 386 | speed many implementations including router implementations. | ||
| 387 | |||
| 388 | |||
| 389 | |||
| 390 | |||
| 391 | |||
| 392 | Internet Draft, Expires 15 Jan 93 [PAGE 6] | ||
| 393 | |||
| 394 | |||
| 395 | |||
| 396 | CIPSO INTERNET DRAFT 16 July, 1992 | ||
| 397 | |||
| 398 | |||
| 399 | |||
| 400 | 3.4.4.4 Sensitivity Level | ||
| 401 | |||
| 402 | This field is 1 octet in length. Its value is from 0 to 255. The values | ||
| 403 | are ordered with 0 being the minimum value and 255 representing the maximum | ||
| 404 | value. | ||
| 405 | |||
| 406 | |||
| 407 | 3.4.4.5 Category Ranges | ||
| 408 | |||
| 409 | A category range is a 4 octet field comprised of the 2 octet index of the | ||
| 410 | highest numbered category followed by the 2 octet index of the lowest | ||
| 411 | numbered category. These range endpoints are inclusive within the range of | ||
| 412 | categories. All categories within a range are included in the sensitivity | ||
| 413 | label. This tag may contain a maximum of 7 category pairs. The bottom | ||
| 414 | category endpoint for the last pair in the tag MAY be omitted and SHOULD be | ||
| 415 | assumed to be 0. The ranges MUST be non-overlapping and be listed in | ||
| 416 | descending order. Valid values for categories are 0 to 65534. Category | ||
| 417 | 65535 is not a valid category value. | ||
| 418 | |||
| 419 | |||
| 420 | 3.4.5 Minimum Requirements | ||
| 421 | |||
| 422 | A CIPSO implementation MUST be capable of generating at least tag type 1 in | ||
| 423 | the non-optimized form. In addition, a CIPSO implementation MUST be able | ||
| 424 | to receive any valid tag type 1 even those using the optimized tag type 1 | ||
| 425 | format. | ||
| 426 | |||
| 427 | |||
| 428 | 4. Configuration Parameters | ||
| 429 | |||
| 430 | The configuration parameters defined below are required for all CIPSO hosts, | ||
| 431 | gateways, and routers that support multiple sensitivity labels. A CIPSO | ||
| 432 | host is defined to be the origination or destination system for an IP | ||
| 433 | datagram. A CIPSO gateway provides IP routing services between two or more | ||
| 434 | IP networks and may be required to perform label translations between | ||
| 435 | networks. A CIPSO gateway may be an enhanced CIPSO host or it may just | ||
| 436 | provide gateway services with no end system CIPSO capabilities. A CIPSO | ||
| 437 | router is a dedicated IP router that routes IP datagrams between two or more | ||
| 438 | IP networks. | ||
| 439 | |||
| 440 | An implementation of CIPSO on a host MUST have the capability to reject a | ||
| 441 | datagram for reasons that the information contained can not be adequately | ||
| 442 | protected by the receiving host or if acceptance may result in violation of | ||
| 443 | the host or network security policy. In addition, a CIPSO gateway or router | ||
| 444 | MUST be able to reject datagrams going to networks that can not provide | ||
| 445 | adequate protection or may violate the network's security policy. To | ||
| 446 | provide this capability the following minimal set of configuration | ||
| 447 | parameters are required for CIPSO implementations: | ||
| 448 | |||
| 449 | HOST_LABEL_MAX - This parameter contains the maximum sensitivity label that | ||
| 450 | a CIPSO host is authorized to handle. All datagrams that have a label | ||
| 451 | greater than this maximum MUST be rejected by the CIPSO host. This | ||
| 452 | parameter does not apply to CIPSO gateways or routers. This parameter need | ||
| 453 | not be defined explicitly as it can be implicitly derived from the | ||
| 454 | PORT_LABEL_MAX parameters for the associated interfaces. | ||
| 455 | |||
| 456 | |||
| 457 | |||
| 458 | Internet Draft, Expires 15 Jan 93 [PAGE 7] | ||
| 459 | |||
| 460 | |||
| 461 | |||
| 462 | CIPSO INTERNET DRAFT 16 July, 1992 | ||
| 463 | |||
| 464 | |||
| 465 | |||
| 466 | |||
| 467 | HOST_LABEL_MIN - This parameter contains the minimum sensitivity label that | ||
| 468 | a CIPSO host is authorized to handle. All datagrams that have a label less | ||
| 469 | than this minimum MUST be rejected by the CIPSO host. This parameter does | ||
| 470 | not apply to CIPSO gateways or routers. This parameter need not be defined | ||
| 471 | explicitly as it can be implicitly derived from the PORT_LABEL_MIN | ||
| 472 | parameters for the associated interfaces. | ||
| 473 | |||
| 474 | PORT_LABEL_MAX - This parameter contains the maximum sensitivity label for | ||
| 475 | all datagrams that may exit a particular network interface port. All | ||
| 476 | outgoing datagrams that have a label greater than this maximum MUST be | ||
| 477 | rejected by the CIPSO system. The label within this parameter MUST be | ||
| 478 | less than or equal to the label within the HOST_LABEL_MAX parameter. This | ||
| 479 | parameter does not apply to CIPSO hosts that support only one network port. | ||
| 480 | |||
| 481 | PORT_LABEL_MIN - This parameter contains the minimum sensitivity label for | ||
| 482 | all datagrams that may exit a particular network interface port. All | ||
| 483 | outgoing datagrams that have a label less than this minimum MUST be | ||
| 484 | rejected by the CIPSO system. The label within this parameter MUST be | ||
| 485 | greater than or equal to the label within the HOST_LABEL_MIN parameter. | ||
| 486 | This parameter does not apply to CIPSO hosts that support only one network | ||
| 487 | port. | ||
| 488 | |||
| 489 | PORT_DOI - This parameter is used to assign a DOI identifier value to a | ||
| 490 | particular network interface port. All CIPSO labels within datagrams | ||
| 491 | going out this port MUST use the specified DOI identifier. All CIPSO | ||
| 492 | hosts and gateways MUST support either this parameter, the NET_DOI | ||
| 493 | parameter, or the HOST_DOI parameter. | ||
| 494 | |||
| 495 | NET_DOI - This parameter is used to assign a DOI identifier value to a | ||
| 496 | particular IP network address. All CIPSO labels within datagrams destined | ||
| 497 | for the particular IP network MUST use the specified DOI identifier. All | ||
| 498 | CIPSO hosts and gateways MUST support either this parameter, the PORT_DOI | ||
| 499 | parameter, or the HOST_DOI parameter. | ||
| 500 | |||
| 501 | HOST_DOI - This parameter is used to assign a DOI identifier value to a | ||
| 502 | particular IP host address. All CIPSO labels within datagrams destined for | ||
| 503 | the particular IP host will use the specified DOI identifier. All CIPSO | ||
| 504 | hosts and gateways MUST support either this parameter, the PORT_DOI | ||
| 505 | parameter, or the NET_DOI parameter. | ||
| 506 | |||
| 507 | This list represents the minimal set of configuration parameters required | ||
| 508 | to be compliant. Implementors are encouraged to add to this list to | ||
| 509 | provide enhanced functionality and control. For example, many security | ||
| 510 | policies may require both incoming and outgoing datagrams be checked against | ||
| 511 | the port and host label ranges. | ||
| 512 | |||
| 513 | |||
| 514 | 4.1 Port Range Parameters | ||
| 515 | |||
| 516 | The labels represented by the PORT_LABEL_MAX and PORT_LABEL_MIN parameters | ||
| 517 | MAY be in CIPSO or local format. Some CIPSO systems, such as routers, may | ||
| 518 | want to have the range parameters expressed in CIPSO format so that incoming | ||
| 519 | labels do not have to be converted to a local format before being compared | ||
| 520 | against the range. If multiple DOIs are supported by one of these CIPSO | ||
| 521 | |||
| 522 | |||
| 523 | |||
| 524 | Internet Draft, Expires 15 Jan 93 [PAGE 8] | ||
| 525 | |||
| 526 | |||
| 527 | |||
| 528 | CIPSO INTERNET DRAFT 16 July, 1992 | ||
| 529 | |||
| 530 | |||
| 531 | |||
| 532 | systems then multiple port range parameters would be needed, one set for | ||
| 533 | each DOI supported on a particular port. | ||
| 534 | |||
| 535 | The port range will usually represent the total set of labels that may | ||
| 536 | exist on the logical network accessed through the corresponding network | ||
| 537 | interface. It may, however, represent a subset of these labels that are | ||
| 538 | allowed to enter the CIPSO system. | ||
| 539 | |||
| 540 | |||
| 541 | 4.2 Single Label CIPSO Hosts | ||
| 542 | |||
| 543 | CIPSO implementations that support only one label are not required to | ||
| 544 | support the parameters described above. These limited implementations are | ||
| 545 | only required to support a NET_LABEL parameter. This parameter contains | ||
| 546 | the CIPSO label that may be inserted in datagrams that exit the host. In | ||
| 547 | addition, the host MUST reject any incoming datagram that has a label which | ||
| 548 | is not equivalent to the NET_LABEL parameter. | ||
| 549 | |||
| 550 | |||
| 551 | 5. Handling Procedures | ||
| 552 | |||
| 553 | This section describes the processing requirements for incoming and | ||
| 554 | outgoing IP datagrams. Just providing the correct CIPSO label format | ||
| 555 | is not enough. Assumptions will be made by one system on how a | ||
| 556 | receiving system will handle the CIPSO label. Wrong assumptions may | ||
| 557 | lead to non-interoperability or even a security incident. The | ||
| 558 | requirements described below represent the minimal set needed for | ||
| 559 | interoperability and that provide users some level of confidence. | ||
| 560 | Many other requirements could be added to increase user confidence, | ||
| 561 | however at the risk of restricting creativity and limiting vendor | ||
| 562 | participation. | ||
| 563 | |||
| 564 | |||
| 565 | 5.1 Input Procedures | ||
| 566 | |||
| 567 | All datagrams received through a network port MUST have a security label | ||
| 568 | associated with them, either contained in the datagram or assigned to the | ||
| 569 | receiving port. Without this label the host, gateway, or router will not | ||
| 570 | have the information it needs to make security decisions. This security | ||
| 571 | label will be obtained from the CIPSO if the option is present in the | ||
| 572 | datagram. See section 4.1.2 for handling procedures for unlabeled | ||
| 573 | datagrams. This label will be compared against the PORT (if appropriate) | ||
| 574 | and HOST configuration parameters defined in section 3. | ||
| 575 | |||
| 576 | If any field within the CIPSO option, such as the DOI identifier, is not | ||
| 577 | recognized the IP datagram is discarded and an ICMP "parameter problem" | ||
| 578 | (type 12) is generated and returned. The ICMP code field is set to "bad | ||
| 579 | parameter" (code 0) and the pointer is set to the start of the CIPSO field | ||
| 580 | that is unrecognized. | ||
| 581 | |||
| 582 | If the contents of the CIPSO are valid but the security label is | ||
| 583 | outside of the configured host or port label range, the datagram is | ||
| 584 | discarded and an ICMP "destination unreachable" (type 3) is generated | ||
| 585 | and returned. The code field of the ICMP is set to "communication with | ||
| 586 | destination network administratively prohibited" (code 9) or to | ||
| 587 | |||
| 588 | |||
| 589 | |||
| 590 | Internet Draft, Expires 15 Jan 93 [PAGE 9] | ||
| 591 | |||
| 592 | |||
| 593 | |||
| 594 | CIPSO INTERNET DRAFT 16 July, 1992 | ||
| 595 | |||
| 596 | |||
| 597 | |||
| 598 | "communication with destination host administratively prohibited" | ||
| 599 | (code 10). The value of the code field used is dependent upon whether | ||
| 600 | the originator of the ICMP message is acting as a CIPSO host or a CIPSO | ||
| 601 | gateway. The recipient of the ICMP message MUST be able to handle either | ||
| 602 | value. The same procedure is performed if a CIPSO can not be added to an | ||
| 603 | IP packet because it is too large to fit in the IP options area. | ||
| 604 | |||
| 605 | If the error is triggered by receipt of an ICMP message, the message | ||
| 606 | is discarded and no response is permitted (consistent with general ICMP | ||
| 607 | processing rules). | ||
| 608 | |||
| 609 | |||
| 610 | 5.1.1 Unrecognized tag types | ||
| 611 | |||
| 612 | The default condition for any CIPSO implementation is that an | ||
| 613 | unrecognized tag type MUST be treated as a "parameter problem" and | ||
| 614 | handled as described in section 4.1. A CIPSO implementation MAY allow | ||
| 615 | the system administrator to identify tag types that may safely be | ||
| 616 | ignored. This capability is an allowable enhancement, not a | ||
| 617 | requirement. | ||
| 618 | |||
| 619 | |||
| 620 | 5.1.2 Unlabeled Packets | ||
| 621 | |||
| 622 | A network port may be configured to not require a CIPSO label for all | ||
| 623 | incoming datagrams. For this configuration a CIPSO label must be | ||
| 624 | assigned to that network port and associated with all unlabeled IP | ||
| 625 | datagrams. This capability might be used for single level networks or | ||
| 626 | networks that have CIPSO and non-CIPSO hosts and the non-CIPSO hosts | ||
| 627 | all operate at the same label. | ||
| 628 | |||
| 629 | If a CIPSO option is required and none is found, the datagram is | ||
| 630 | discarded and an ICMP "parameter problem" (type 12) is generated and | ||
| 631 | returned to the originator of the datagram. The code field of the ICMP | ||
| 632 | is set to "option missing" (code 1) and the ICMP pointer is set to 134 | ||
| 633 | (the value of the option type for the missing CIPSO option). | ||
| 634 | |||
| 635 | |||
| 636 | 5.2 Output Procedures | ||
| 637 | |||
| 638 | A CIPSO option MUST appear only once in a datagram. Only one tag type | ||
| 639 | from the MAC Sensitivity class MAY be included in a CIPSO option. Given | ||
| 640 | the current set of defined tag types, this means that CIPSO labels at | ||
| 641 | first will contain only one tag. | ||
| 642 | |||
| 643 | All datagrams leaving a CIPSO system MUST meet the following condition: | ||
| 644 | |||
| 645 | PORT_LABEL_MIN <= CIPSO label <= PORT_LABEL_MAX | ||
| 646 | |||
| 647 | If this condition is not satisfied the datagram MUST be discarded. | ||
| 648 | If the CIPSO system only supports one port, the HOST_LABEL_MIN and the | ||
| 649 | HOST_LABEL_MAX parameters MAY be substituted for the PORT parameters in | ||
| 650 | the above condition. | ||
| 651 | |||
| 652 | The DOI identifier to be used for all outgoing datagrams is configured by | ||
| 653 | |||
| 654 | |||
| 655 | |||
| 656 | Internet Draft, Expires 15 Jan 93 [PAGE 10] | ||
| 657 | |||
| 658 | |||
| 659 | |||
| 660 | CIPSO INTERNET DRAFT 16 July, 1992 | ||
| 661 | |||
| 662 | |||
| 663 | |||
| 664 | the administrator. If port level DOI identifier assignment is used, then | ||
| 665 | the PORT_DOI configuration parameter MUST contain the DOI identifier to | ||
| 666 | use. If network level DOI assignment is used, then the NET_DOI parameter | ||
| 667 | MUST contain the DOI identifier to use. And if host level DOI assignment | ||
| 668 | is employed, then the HOST_DOI parameter MUST contain the DOI identifier | ||
| 669 | to use. A CIPSO implementation need only support one level of DOI | ||
| 670 | assignment. | ||
| 671 | |||
| 672 | |||
| 673 | 5.3 DOI Processing Requirements | ||
| 674 | |||
| 675 | A CIPSO implementation MUST support at least one DOI and SHOULD support | ||
| 676 | multiple DOIs. System and network administrators are cautioned to | ||
| 677 | ensure that at least one DOI is common within an IP network to allow for | ||
| 678 | broadcasting of IP datagrams. | ||
| 679 | |||
| 680 | CIPSO gateways MUST be capable of translating a CIPSO option from one | ||
| 681 | DOI to another when forwarding datagrams between networks. For | ||
| 682 | efficiency purposes this capability is only a desired feature for CIPSO | ||
| 683 | routers. | ||
| 684 | |||
| 685 | |||
| 686 | 5.4 Label of ICMP Messages | ||
| 687 | |||
| 688 | The CIPSO label to be used on all outgoing ICMP messages MUST be equivalent | ||
| 689 | to the label of the datagram that caused the ICMP message. If the ICMP was | ||
| 690 | generated due to a problem associated with the original CIPSO label then the | ||
| 691 | following responses are allowed: | ||
| 692 | |||
| 693 | a. Use the CIPSO label of the original IP datagram | ||
| 694 | b. Drop the original datagram with no return message generated | ||
| 695 | |||
| 696 | In most cases these options will have the same effect. If you can not | ||
| 697 | interpret the label or if it is outside the label range of your host or | ||
| 698 | interface then an ICMP message with the same label will probably not be | ||
| 699 | able to exit the system. | ||
| 700 | |||
| 701 | |||
| 702 | 6. Assignment of DOI Identifier Numbers = | ||
| 703 | |||
| 704 | Requests for assignment of a DOI identifier number should be addressed to | ||
| 705 | the Internet Assigned Numbers Authority (IANA). | ||
| 706 | |||
| 707 | |||
| 708 | 7. Acknowledgements | ||
| 709 | |||
| 710 | Much of the material in this RFC is based on (and copied from) work | ||
| 711 | done by Gary Winiger of Sun Microsystems and published as Commercial | ||
| 712 | IP Security Option at the INTEROP 89, Commercial IPSO Workshop. | ||
| 713 | |||
| 714 | |||
| 715 | 8. Author's Address | ||
| 716 | |||
| 717 | To submit mail for distribution to members of the IETF CIPSO Working | ||
| 718 | Group, send mail to: cipso@wdl1.wdl.loral.com. | ||
| 719 | |||
| 720 | |||
| 721 | |||
| 722 | Internet Draft, Expires 15 Jan 93 [PAGE 11] | ||
| 723 | |||
| 724 | |||
| 725 | |||
| 726 | CIPSO INTERNET DRAFT 16 July, 1992 | ||
| 727 | |||
| 728 | |||
| 729 | |||
| 730 | |||
| 731 | To be added to or deleted from this distribution, send mail to: | ||
| 732 | cipso-request@wdl1.wdl.loral.com. | ||
| 733 | |||
| 734 | |||
| 735 | 9. References | ||
| 736 | |||
| 737 | RFC 1038, "Draft Revised IP Security Option", M. St. Johns, IETF, January | ||
| 738 | 1988. | ||
| 739 | |||
| 740 | RFC 1108, "U.S. Department of Defense Security Options | ||
| 741 | for the Internet Protocol", Stephen Kent, IAB, 1 March, 1991. | ||
| 742 | |||
| 743 | |||
| 744 | |||
| 745 | |||
| 746 | |||
| 747 | |||
| 748 | |||
| 749 | |||
| 750 | |||
| 751 | |||
| 752 | |||
| 753 | |||
| 754 | |||
| 755 | |||
| 756 | |||
| 757 | |||
| 758 | |||
| 759 | |||
| 760 | |||
| 761 | |||
| 762 | |||
| 763 | |||
| 764 | |||
| 765 | |||
| 766 | |||
| 767 | |||
| 768 | |||
| 769 | |||
| 770 | |||
| 771 | |||
| 772 | |||
| 773 | |||
| 774 | |||
| 775 | |||
| 776 | |||
| 777 | |||
| 778 | |||
| 779 | |||
| 780 | |||
| 781 | |||
| 782 | |||
| 783 | |||
| 784 | |||
| 785 | |||
| 786 | |||
| 787 | |||
| 788 | Internet Draft, Expires 15 Jan 93 [PAGE 12] | ||
| 789 | |||
| 790 | |||
| 791 | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | NetLabel Introduction | ||
| 2 | ============================================================================== | ||
| 3 | Paul Moore, paul.moore@hp.com | ||
| 4 | |||
| 5 | August 2, 2006 | ||
| 6 | |||
| 7 | * Overview | ||
| 8 | |||
| 9 | NetLabel is a mechanism which can be used by kernel security modules to attach | ||
| 10 | security attributes to outgoing network packets generated from user space | ||
| 11 | applications and read security attributes from incoming network packets. It | ||
| 12 | is composed of three main components, the protocol engines, the communication | ||
| 13 | layer, and the kernel security module API. | ||
| 14 | |||
| 15 | * Protocol Engines | ||
| 16 | |||
| 17 | The protocol engines are responsible for both applying and retrieving the | ||
| 18 | network packet's security attributes. If any translation between the network | ||
| 19 | security attributes and those on the host are required then the protocol | ||
| 20 | engine will handle those tasks as well. Other kernel subsystems should | ||
| 21 | refrain from calling the protocol engines directly, instead they should use | ||
| 22 | the NetLabel kernel security module API described below. | ||
| 23 | |||
| 24 | Detailed information about each NetLabel protocol engine can be found in this | ||
| 25 | directory, consult '00-INDEX' for filenames. | ||
| 26 | |||
| 27 | * Communication Layer | ||
| 28 | |||
| 29 | The communication layer exists to allow NetLabel configuration and monitoring | ||
| 30 | from user space. The NetLabel communication layer uses a message based | ||
| 31 | protocol built on top of the Generic NETLINK transport mechanism. The exact | ||
| 32 | formatting of these NetLabel messages as well as the Generic NETLINK family | ||
| 33 | names can be found in the the 'net/netlabel/' directory as comments in the | ||
| 34 | header files as well as in 'include/net/netlabel.h'. | ||
| 35 | |||
| 36 | * Security Module API | ||
| 37 | |||
| 38 | The purpose of the NetLabel security module API is to provide a protocol | ||
| 39 | independent interface to the underlying NetLabel protocol engines. In addition | ||
| 40 | to protocol independence, the security module API is designed to be completely | ||
| 41 | LSM independent which should allow multiple LSMs to leverage the same code | ||
| 42 | base. | ||
| 43 | |||
| 44 | Detailed information about the NetLabel security module API can be found in the | ||
| 45 | 'include/net/netlabel.h' header file as well as the 'lsm_interface.txt' file | ||
| 46 | found in this directory. | ||
| @@ -0,0 +1,47 @@ | |||
| 1 | NetLabel Linux Security Module Interface | ||
| 2 | ============================================================================== | ||
| 3 | Paul Moore, paul.moore@hp.com | ||
| 4 | |||
| 5 | May 17, 2006 | ||
| 6 | |||
| 7 | * Overview | ||
| 8 | |||
| 9 | NetLabel is a mechanism which can set and retrieve security attributes from | ||
| 10 | network packets. It is intended to be used by LSM developers who want to make | ||
| 11 | use of a common code base for several different packet labeling protocols. | ||
| 12 | The NetLabel security module API is defined in 'include/net/netlabel.h' but a | ||
| 13 | brief overview is given below. | ||
| 14 | |||
| 15 | * NetLabel Security Attributes | ||
| 16 | |||
| 17 | Since NetLabel supports multiple different packet labeling protocols and LSMs | ||
| 18 | it uses the concept of security attributes to refer to the packet's security | ||
| 19 | labels. The NetLabel security attributes are defined by the | ||
| 20 | 'netlbl_lsm_secattr' structure in the NetLabel header file. Internally the | ||
| 21 | NetLabel subsystem converts the security attributes to and from the correct | ||
| 22 | low-level packet label depending on the NetLabel build time and run time | ||
| 23 | configuration. It is up to the LSM developer to translate the NetLabel | ||
| 24 | security attributes into whatever security identifiers are in use for their | ||
| 25 | particular LSM. | ||
| 26 | |||
| 27 | * NetLabel LSM Protocol Operations | ||
| 28 | |||
| 29 | These are the functions which allow the LSM developer to manipulate the labels | ||
| 30 | on outgoing packets as well as read the labels on incoming packets. Functions | ||
| 31 | exist to operate both on sockets as well as the sk_buffs directly. These high | ||
| 32 | level functions are translated into low level protocol operations based on how | ||
| 33 | the administrator has configured the NetLabel subsystem. | ||
| 34 | |||
| 35 | * NetLabel Label Mapping Cache Operations | ||
| 36 | |||
| 37 | Depending on the exact configuration, translation between the network packet | ||
| 38 | label and the internal LSM security identifier can be time consuming. The | ||
| 39 | NetLabel label mapping cache is a caching mechanism which can be used to | ||
| 40 | sidestep much of this overhead once a mapping has been established. Once the | ||
| 41 | LSM has received a packet, used NetLabel to decode it's security attributes, | ||
| 42 | and translated the security attributes into a LSM internal identifier the LSM | ||
| 43 | can use the NetLabel caching functions to associate the LSM internal | ||
| 44 | identifier with the network packet's label. This means that in the future | ||
| 45 | when a incoming packet matches a cached value not only are the internal | ||
| 46 | NetLabel translation mechanisms bypassed but the LSM translation mechanisms are | ||
| 47 | bypassed as well which should result in a significant reduction in overhead. | ||
| @@ -375,6 +375,41 @@ tcp_slow_start_after_idle - BOOLEAN · 374 unmodified lines | |||
| 375 | be timed out after an idle period. | 375 | be timed out after an idle period. |
| 376 | Default: 1 | 376 | Default: 1 |
| 377 | 377 | ||
| 378 | CIPSOv4 Variables: | ||
| 379 | |||
| 380 | cipso_cache_enable - BOOLEAN | ||
| 381 | If set, enable additions to and lookups from the CIPSO label mapping | ||
| 382 | cache. If unset, additions are ignored and lookups always result in a | ||
| 383 | miss. However, regardless of the setting the cache is still | ||
| 384 | invalidated when required when means you can safely toggle this on and | ||
| 385 | off and the cache will always be "safe". | ||
| 386 | Default: 1 | ||
| 387 | |||
| 388 | cipso_cache_bucket_size - INTEGER | ||
| 389 | The CIPSO label cache consists of a fixed size hash table with each | ||
| 390 | hash bucket containing a number of cache entries. This variable limits | ||
| 391 | the number of entries in each hash bucket; the larger the value the | ||
| 392 | more CIPSO label mappings that can be cached. When the number of | ||
| 393 | entries in a given hash bucket reaches this limit adding new entries | ||
| 394 | causes the oldest entry in the bucket to be removed to make room. | ||
| 395 | Default: 10 | ||
| 396 | |||
| 397 | cipso_rbm_optfmt - BOOLEAN | ||
| 398 | Enable the "Optimized Tag 1 Format" as defined in section 3.4.2.6 of | ||
| 399 | the CIPSO draft specification (see Documentation/netlabel for details). | ||
| 400 | This means that when set the CIPSO tag will be padded with empty | ||
| 401 | categories in order to make the packet data 32-bit aligned. | ||
| 402 | Default: 0 | ||
| 403 | |||
| 404 | cipso_rbm_structvalid - BOOLEAN | ||
| 405 | If set, do a very strict check of the CIPSO option when | ||
| 406 | ip_options_compile() is called. If unset, relax the checks done during | ||
| 407 | ip_options_compile(). Either way is "safe" as errors are caught else | ||
| 408 | where in the CIPSO processing code but setting this to 0 (False) should | ||
| 409 | result in less work (i.e. it should be faster) but could cause problems | ||
| 410 | with other implementations that require strict checking. | ||
| 411 | Default: 0 | ||
| 412 | |||
| 378 | IP Variables: | 413 | IP Variables: |
| 379 | 414 | ||
| 380 | ip_local_port_range - 2 INTEGERS | 415 | ip_local_port_range - 2 INTEGERS |
| @@ -730,6 +765,9 @@ conf/all/forwarding - BOOLEAN · 349 unmodified lines | |||
| 730 | 765 | ||
| 731 | This referred to as global forwarding. | 766 | This referred to as global forwarding. |
| 732 | 767 | ||
| 768 | proxy_ndp - BOOLEAN | ||
| 769 | Do proxy ndp. | ||
| 770 | |||
| 733 | conf/interface/*: | 771 | conf/interface/*: |
| 734 | Change special settings per interface. | 772 | Change special settings per interface. |
| 735 | 773 | ||
| @@ -0,0 +1,14 @@ | |||
| 1 | flowi structure: | ||
| 2 | |||
| 3 | The secid member in the flow structure is used in LSMs (e.g. SELinux) to indicate | ||
| 4 | the label of the flow. This label of the flow is currently used in selecting | ||
| 5 | matching labeled xfrm(s). | ||
| 6 | |||
| 7 | If this is an outbound flow, the label is derived from the socket, if any, or | ||
| 8 | the incoming packet this flow is being generated as a response to (e.g. tcp | ||
| 9 | resets, timewait ack, etc.). It is also conceivable that the label could be | ||
| 10 | derived from other sources such as process context, device, etc., in special | ||
| 11 | cases, as may be appropriate. | ||
| 12 | |||
| 13 | If this is an inbound flow, the label is derived from the IPSec security | ||
| 14 | associations, if any, used by the packet. | ||
| @@ -758,6 +758,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. · 757 unmodified lines | |||
| 758 | position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) | 758 | position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) |
| 759 | single_cmd - Use single immediate commands to communicate with | 759 | single_cmd - Use single immediate commands to communicate with |
| 760 | codecs (for debugging only) | 760 | codecs (for debugging only) |
| 761 | disable_msi - Disable Message Signaled Interrupt (MSI) | ||
| 761 | 762 | ||
| 762 | This module supports one card and autoprobe. | 763 | This module supports one card and autoprobe. |
| 763 | 764 | ||
| @@ -778,11 +779,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. · 14 unmodified lines | |||
| 778 | 6stack-digout 6-jack with a SPDIF out | 779 | 6stack-digout 6-jack with a SPDIF out |
| 779 | w810 3-jack | 780 | w810 3-jack |
| 780 | z71v 3-jack (HP shared SPDIF) | 781 | z71v 3-jack (HP shared SPDIF) |
| 781 | asus 3-jack | 782 | asus 3-jack (ASUS Mobo) |
| 783 | asus-w1v ASUS W1V | ||
| 784 | asus-dig ASUS with SPDIF out | ||
| 785 | asus-dig2 ASUS with SPDIF out (using GPIO2) | ||
| 782 | uniwill 3-jack | 786 | uniwill 3-jack |
| 783 | F1734 2-jack | 787 | F1734 2-jack |
| 784 | lg LG laptop (m1 express dual) | 788 | lg LG laptop (m1 express dual) |
| 785 | lg-lw LG LW20 laptop | 789 | lg-lw LG LW20/LW25 laptop |
| 790 | tcl TCL S700 | ||
| 791 | clevo Clevo laptops (m520G, m665n) | ||
| 786 | test for testing/debugging purpose, almost all controls can be | 792 | test for testing/debugging purpose, almost all controls can be |
| 787 | adjusted. Appearing only when compiled with | 793 | adjusted. Appearing only when compiled with |
| 788 | $CONFIG_SND_DEBUG=y | 794 | $CONFIG_SND_DEBUG=y |
| @@ -790,6 +796,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. · 1 unmodified line | |||
| 790 | 796 | ||
| 791 | ALC260 | 797 | ALC260 |
| 792 | hp HP machines | 798 | hp HP machines |
| 799 | hp-3013 HP machines (3013-variant) | ||
| 793 | fujitsu Fujitsu S7020 | 800 | fujitsu Fujitsu S7020 |
| 794 | acer Acer TravelMate | 801 | acer Acer TravelMate |
| 795 | basic fixed pin assignment (old default model) | 802 | basic fixed pin assignment (old default model) |
| @@ -797,24 +804,32 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. · 1 unmodified line | |||
| 797 | 804 | ||
| 798 | ALC262 | 805 | ALC262 |
| 799 | fujitsu Fujitsu Laptop | 806 | fujitsu Fujitsu Laptop |
| 807 | hp-bpc HP xw4400/6400/8400/9400 laptops | ||
| 808 | benq Benq ED8 | ||
| 800 | basic fixed pin assignment w/o SPDIF | 809 | basic fixed pin assignment w/o SPDIF |
| 801 | auto auto-config reading BIOS (default) | 810 | auto auto-config reading BIOS (default) |
| 802 | 811 | ||
| 803 | ALC882/885 | 812 | ALC882/885 |
| 804 | 3stack-dig 3-jack with SPDIF I/O | 813 | 3stack-dig 3-jack with SPDIF I/O |
| 805 | 6stck-dig 6-jack digital with SPDIF I/O | 814 | 6stck-dig 6-jack digital with SPDIF I/O |
| 815 | arima Arima W820Di1 | ||
| 806 | auto auto-config reading BIOS (default) | 816 | auto auto-config reading BIOS (default) |
| 807 | 817 | ||
| 808 | ALC883/888 | 818 | ALC883/888 |
| 809 | 3stack-dig 3-jack with SPDIF I/O | 819 | 3stack-dig 3-jack with SPDIF I/O |
| 810 | 6stack-dig 6-jack digital with SPDIF I/O | 820 | 6stack-dig 6-jack digital with SPDIF I/O |
| 811 | 6stack-dig-demo 6-stack digital for Intel demo board | 821 | 3stack-6ch 3-jack 6-channel |
| 822 | 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O | ||
| 823 | 6stack-dig-demo 6-jack digital for Intel demo board | ||
| 824 | acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) | ||
| 812 | auto auto-config reading BIOS (default) | 825 | auto auto-config reading BIOS (default) |
| 813 | 826 | ||
| 814 | ALC861/660 | 827 | ALC861/660 |
| 815 | 3stack 3-jack | 828 | 3stack 3-jack |
| 816 | 3stack-dig 3-jack with SPDIF I/O | 829 | 3stack-dig 3-jack with SPDIF I/O |
| 817 | 6stack-dig 6-jack with SPDIF I/O | 830 | 6stack-dig 6-jack with SPDIF I/O |
| 831 | 3stack-660 3-jack (for ALC660) | ||
| 832 | uniwill-m31 Uniwill M31 laptop | ||
| 818 | auto auto-config reading BIOS (default) | 833 | auto auto-config reading BIOS (default) |
| 819 | 834 | ||
| 820 | CMI9880 | 835 | CMI9880 |
| @@ -843,10 +858,21 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. · 22 unmodified lines | |||
| 843 | 3stack-dig ditto with SPDIF | 858 | 3stack-dig ditto with SPDIF |
| 844 | laptop 3-jack with hp-jack automute | 859 | laptop 3-jack with hp-jack automute |
| 845 | laptop-dig ditto with SPDIF | 860 | laptop-dig ditto with SPDIF |
| 846 | auto auto-confgi reading BIOS (default) | 861 | auto auto-config reading BIOS (default) |
| 862 | |||
| 863 | STAC9200/9205/9220/9221/9254 | ||
| 864 | ref Reference board | ||
| 865 | 3stack D945 3stack | ||
| 866 | 5stack D945 5stack + SPDIF | ||
| 847 | 867 | ||
| 848 | STAC7661(?) | 868 | STAC9227/9228/9229/927x |
| 869 | ref Reference board | ||
| 870 | 3stack D965 3stack | ||
| 871 | 5stack D965 5stack + SPDIF | ||
| 872 | |||
| 873 | STAC9872 | ||
| 849 | vaio Setup for VAIO FE550G/SZ110 | 874 | vaio Setup for VAIO FE550G/SZ110 |
| 875 | vaio-ar Setup for VAIO AR | ||
| 850 | 876 | ||
| 851 | If the default configuration doesn't work and one of the above | 877 | If the default configuration doesn't work and one of the above |
| 852 | matches with your device, report it together with the PCI | 878 | matches with your device, report it together with the PCI |
| @@ -1213,6 +1239,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. · 360 unmodified lines | |||
| 1213 | 1239 | ||
| 1214 | Module supports only 1 card. This module has no enable option. | 1240 | Module supports only 1 card. This module has no enable option. |
| 1215 | 1241 | ||
| 1242 | Module snd-mts64 | ||
| 1243 | ---------------- | ||
| 1244 | |||
| 1245 | Module for Ego Systems (ESI) Miditerminal 4140 | ||
| 1246 | |||
| 1247 | This module supports multiple devices. | ||
| 1248 | Requires parport (CONFIG_PARPORT). | ||
| 1249 | |||
| 1216 | Module snd-nm256 | 1250 | Module snd-nm256 |
| 1217 | ---------------- | 1251 | ---------------- |
| 1218 | 1252 | ||
| @@ -1054,9 +1054,8 @@ · 1053 unmodified lines | |||
| 1054 | 1054 | ||
| 1055 | <para> | 1055 | <para> |
| 1056 | For a device which allows hotplugging, you can use | 1056 | For a device which allows hotplugging, you can use |
| 1057 | <function>snd_card_free_in_thread</function>. This one will | 1057 | <function>snd_card_free_when_closed</function>. This one will |
| 1058 | postpone the destruction and wait in a kernel-thread until all | 1058 | postpone the destruction until all devices are closed. |
| 1059 | devices are closed. | ||
| 1060 | </para> | 1059 | </para> |
| 1061 | 1060 | ||
| 1062 | </section> | 1061 | </section> |
| @@ -1058,8 +1058,8 @@ core99_reset_cpu(struct device_node *node, long param, long value) · 1057 unmodified lines | |||
| 1058 | if (np == NULL) | 1058 | if (np == NULL) |
| 1059 | return -ENODEV; | 1059 | return -ENODEV; |
| 1060 | for (np = np->child; np != NULL; np = np->sibling) { | 1060 | for (np = np->child; np != NULL; np = np->sibling) { |
| 1061 | u32 *num = get_property(np, "reg", NULL); | 1061 | const u32 *num = get_property(np, "reg", NULL); |
| 1062 | u32 *rst = get_property(np, "soft-reset", NULL); | 1062 | const u32 *rst = get_property(np, "soft-reset", NULL); |
| 1063 | if (num == NULL || rst == NULL) | 1063 | if (num == NULL || rst == NULL) |
| 1064 | continue; | 1064 | continue; |
| 1065 | if (param == *num) { | 1065 | if (param == *num) { |
| @@ -702,7 +702,7 @@ static void __init smp_core99_setup(int ncpus) · 701 unmodified lines | |||
| 702 | /* GPIO based HW sync on ppc32 Core99 */ | 702 | /* GPIO based HW sync on ppc32 Core99 */ |
| 703 | if (pmac_tb_freeze == NULL && !machine_is_compatible("MacRISC4")) { | 703 | if (pmac_tb_freeze == NULL && !machine_is_compatible("MacRISC4")) { |
| 704 | struct device_node *cpu; | 704 | struct device_node *cpu; |
| 705 | u32 *tbprop = NULL; | 705 | const u32 *tbprop = NULL; |
| 706 | 706 | ||
| 707 | core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */ | 707 | core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */ |
| 708 | cpu = of_find_node_by_type(NULL, "cpu"); | 708 | cpu = of_find_node_by_type(NULL, "cpu"); |
| @@ -2801,6 +2801,18 @@ long blk_congestion_wait(int rw, long timeout) · 2800 unmodified lines | |||
| 2801 | 2801 | ||
| 2802 | EXPORT_SYMBOL(blk_congestion_wait); | 2802 | EXPORT_SYMBOL(blk_congestion_wait); |
| 2803 | 2803 | ||
| 2804 | /** | ||
| 2805 | * blk_congestion_end - wake up sleepers on a congestion queue | ||
| 2806 | * @rw: READ or WRITE | ||
| 2807 | */ | ||
| 2808 | void blk_congestion_end(int rw) | ||
| 2809 | { | ||
| 2810 | wait_queue_head_t *wqh = &congestion_wqh[rw]; | ||
| 2811 | |||
| 2812 | if (waitqueue_active(wqh)) | ||
| 2813 | wake_up(wqh); | ||
| 2814 | } | ||
| 2815 | |||
| 2804 | /* | 2816 | /* |
| 2805 | * Has to be called with the request spinlock acquired | 2817 | * Has to be called with the request spinlock acquired |
| 2806 | */ | 2818 | */ |
| @@ -92,13 +92,17 @@ static int hmac_init(struct hash_desc *pdesc) · 91 unmodified lines | |||
| 92 | struct hmac_ctx *ctx = align_ptr(ipad + bs * 2 + ds, sizeof(void *)); | 92 | struct hmac_ctx *ctx = align_ptr(ipad + bs * 2 + ds, sizeof(void *)); |
| 93 | struct hash_desc desc; | 93 | struct hash_desc desc; |
| 94 | struct scatterlist tmp; | 94 | struct scatterlist tmp; |
| 95 | int err; | ||
| 95 | 96 | ||
| 96 | desc.tfm = ctx->child; | 97 | desc.tfm = ctx->child; |
| 97 | desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; | 98 | desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; |
| 98 | sg_set_buf(&tmp, ipad, bs); | 99 | sg_set_buf(&tmp, ipad, bs); |
| 99 | 100 | ||
| 100 | return unlikely(crypto_hash_init(&desc)) ?: | 101 | err = crypto_hash_init(&desc); |
| 101 | crypto_hash_update(&desc, &tmp, 1); | 102 | if (unlikely(err)) |
| 103 | return err; | ||
| 104 | |||
| 105 | return crypto_hash_update(&desc, &tmp, bs); | ||
| 102 | } | 106 | } |
| 103 | 107 | ||
| 104 | static int hmac_update(struct hash_desc *pdesc, | 108 | static int hmac_update(struct hash_desc *pdesc, |
| @@ -123,13 +127,17 @@ static int hmac_final(struct hash_desc *pdesc, u8 *out) · 18 unmodified lines | |||
| 123 | struct hmac_ctx *ctx = align_ptr(digest + ds, sizeof(void *)); | 127 | struct hmac_ctx *ctx = align_ptr(digest + ds, sizeof(void *)); |
| 124 | struct hash_desc desc; | 128 | struct hash_desc desc; |
| 125 | struct scatterlist tmp; | 129 | struct scatterlist tmp; |
| 130 | int err; | ||
| 126 | 131 | ||
| 127 | desc.tfm = ctx->child; | 132 | desc.tfm = ctx->child; |
| 128 | desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; | 133 | desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; |
| 129 | sg_set_buf(&tmp, opad, bs + ds); | 134 | sg_set_buf(&tmp, opad, bs + ds); |
| 130 | 135 | ||
| 131 | return unlikely(crypto_hash_final(&desc, digest)) ?: | 136 | err = crypto_hash_final(&desc, digest); |
| 132 | crypto_hash_digest(&desc, &tmp, bs + ds, out); | 137 | if (unlikely(err)) |
| 138 | return err; | ||
| 139 | |||
| 140 | return crypto_hash_digest(&desc, &tmp, bs + ds, out); | ||
| 133 | } | 141 | } |
| 134 | 142 | ||
| 135 | static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg, | 143 | static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg, |
| @@ -145,6 +153,7 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg, · 9 unmodified lines | |||
| 145 | struct hash_desc desc; | 153 | struct hash_desc desc; |
| 146 | struct scatterlist sg1[2]; | 154 | struct scatterlist sg1[2]; |
| 147 | struct scatterlist sg2[1]; | 155 | struct scatterlist sg2[1]; |
| 156 | int err; | ||
| 148 | 157 | ||
| 149 | desc.tfm = ctx->child; | 158 | desc.tfm = ctx->child; |
| 150 | desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; | 159 | desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; |
| @@ -154,8 +163,11 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg, · 3 unmodified lines | |||
| 154 | sg1[1].length = 0; | 163 | sg1[1].length = 0; |
| 155 | sg_set_buf(sg2, opad, bs + ds); | 164 | sg_set_buf(sg2, opad, bs + ds); |
| 156 | 165 | ||
| 157 | return unlikely(crypto_hash_digest(&desc, sg1, nbytes + bs, digest)) ?: | 166 | err = crypto_hash_digest(&desc, sg1, nbytes + bs, digest); |
| 158 | crypto_hash_digest(&desc, sg2, bs + ds, out); | 167 | if (unlikely(err)) |
| 168 | return err; | ||
| 169 | |||
| 170 | return crypto_hash_digest(&desc, sg2, bs + ds, out); | ||
| 159 | } | 171 | } |
| 160 | 172 | ||
| 161 | static int hmac_init_tfm(struct crypto_tfm *tfm) | 173 | static int hmac_init_tfm(struct crypto_tfm *tfm) |
| @@ -1912,7 +1912,7 @@ he_service_rbrq(struct he_dev *he_dev, int group) · 1911 unmodified lines | |||
| 1912 | skb->tail = skb->data + skb->len; | 1912 | skb->tail = skb->data + skb->len; |
| 1913 | #ifdef USE_CHECKSUM_HW | 1913 | #ifdef USE_CHECKSUM_HW |
| 1914 | if (vcc->vpi == 0 && vcc->vci >= ATM_NOT_RSV_VCI) { | 1914 | if (vcc->vpi == 0 && vcc->vci >= ATM_NOT_RSV_VCI) { |
| 1915 | skb->ip_summed = CHECKSUM_HW; | 1915 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 1916 | skb->csum = TCP_CKSUM(skb->data, | 1916 | skb->csum = TCP_CKSUM(skb->data, |
| 1917 | he_vcc->pdu_len); | 1917 | he_vcc->pdu_len); |
| 1918 | } | 1918 | } |
| @@ -87,7 +87,7 @@ static int briq_panel_release(struct inode *ino, struct file *filep) · 86 unmodified lines | |||
| 87 | return 0; | 87 | return 0; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | static ssize_t briq_panel_read(struct file *file, char *buf, size_t count, | 90 | static ssize_t briq_panel_read(struct file *file, char __user *buf, size_t count, |
| 91 | loff_t *ppos) | 91 | loff_t *ppos) |
| 92 | { | 92 | { |
| 93 | unsigned short c; | 93 | unsigned short c; |
| @@ -135,7 +135,7 @@ static void scroll_vfd( void ) · 41 unmodified lines | |||
| 135 | vfd_cursor = 20; | 135 | vfd_cursor = 20; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | static ssize_t briq_panel_write(struct file *file, const char *buf, size_t len, | 138 | static ssize_t briq_panel_write(struct file *file, const char __user *buf, size_t len, |
| 139 | loff_t *ppos) | 139 | loff_t *ppos) |
| 140 | { | 140 | { |
| 141 | size_t indx = len; | 141 | size_t indx = len; |
| @@ -150,19 +150,22 @@ static ssize_t briq_panel_write(struct file *file, const char *buf, size_t len, · 8 unmodified lines | |||
| 150 | return -EBUSY; | 150 | return -EBUSY; |
| 151 | 151 | ||
| 152 | for (;;) { | 152 | for (;;) { |
| 153 | char c; | ||
| 153 | if (!indx) | 154 | if (!indx) |
| 154 | break; | 155 | break; |
| 156 | if (get_user(c, buf)) | ||
| 157 | return -EFAULT; | ||
| 155 | if (esc) { | 158 | if (esc) { |
| 156 | set_led(*buf); | 159 | set_led(c); |
| 157 | esc = 0; | 160 | esc = 0; |
| 158 | } else if (*buf == 27) { | 161 | } else if (c == 27) { |
| 159 | esc = 1; | 162 | esc = 1; |
| 160 | } else if (*buf == 12) { | 163 | } else if (c == 12) { |
| 161 | /* do a form feed */ | 164 | /* do a form feed */ |
| 162 | for (i=0; i<40; i++) | 165 | for (i=0; i<40; i++) |
| 163 | vfd[i] = ' '; | 166 | vfd[i] = ' '; |
| 164 | vfd_cursor = 0; | 167 | vfd_cursor = 0; |
| 165 | } else if (*buf == 10) { | 168 | } else if (c == 10) { |
| 166 | if (vfd_cursor < 20) | 169 | if (vfd_cursor < 20) |
| 167 | vfd_cursor = 20; | 170 | vfd_cursor = 20; |
| 168 | else if (vfd_cursor < 40) | 171 | else if (vfd_cursor < 40) |
| @@ -175,7 +178,7 @@ static ssize_t briq_panel_write(struct file *file, const char *buf, size_t len, · 6 unmodified lines | |||
| 175 | /* just a character */ | 178 | /* just a character */ |
| 176 | if (vfd_cursor > 39) | 179 | if (vfd_cursor > 39) |
| 177 | scroll_vfd(); | 180 | scroll_vfd(); |
| 178 | vfd[vfd_cursor++] = *buf; | 181 | vfd[vfd_cursor++] = c; |
| 179 | } | 182 | } |
| 180 | indx--; | 183 | indx--; |
| 181 | buf++; | 184 | buf++; |
| @@ -202,7 +205,7 @@ static struct miscdevice briq_panel_miscdev = { · 20 unmodified lines | |||
| 202 | static int __init briq_panel_init(void) | 205 | static int __init briq_panel_init(void) |
| 203 | { | 206 | { |
| 204 | struct device_node *root = find_path_device("/"); | 207 | struct device_node *root = find_path_device("/"); |
| 205 | char *machine; | 208 | const char *machine; |
| 206 | int i; | 209 | int i; |
| 207 | 210 | ||
| 208 | machine = get_property(root, "model", NULL); | 211 | machine = get_property(root, "model", NULL); |
| @@ -38,6 +38,7 @@ · 37 unmodified lines | |||
| 38 | #define __IB_MAD_PRIV_H__ | 38 | #define __IB_MAD_PRIV_H__ |
| 39 | 39 | ||
| 40 | #include <linux/completion.h> | 40 | #include <linux/completion.h> |
| 41 | #include <linux/err.h> | ||
| 41 | #include <linux/pci.h> | 42 | #include <linux/pci.h> |
| 42 | #include <linux/workqueue.h> | 43 | #include <linux/workqueue.h> |
| 43 | #include <rdma/ib_mad.h> | 44 | #include <rdma/ib_mad.h> |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | |||
| 49 | #include <linux/init.h> | 49 | #include <linux/init.h> |
| 50 | #include <linux/dma-mapping.h> | 50 | #include <linux/dma-mapping.h> |
| 51 | #include <linux/if_arp.h> | 51 | #include <linux/if_arp.h> |
| 52 | #include <linux/vmalloc.h> | ||
| 52 | 53 | ||
| 53 | #include <asm/io.h> | 54 | #include <asm/io.h> |
| 54 | #include <asm/irq.h> | 55 | #include <asm/irq.h> |
| @@ -50,6 +50,7 @@ · 49 unmodified lines | |||
| 50 | #include <linux/dma-mapping.h> | 50 | #include <linux/dma-mapping.h> |
| 51 | #include <linux/mm.h> | 51 | #include <linux/mm.h> |
| 52 | #include <linux/inet.h> | 52 | #include <linux/inet.h> |
| 53 | #include <linux/vmalloc.h> | ||
| 53 | 54 | ||
| 54 | #include <linux/route.h> | 55 | #include <linux/route.h> |
| 55 | 56 | ||
| @@ -43,6 +43,7 @@ · 42 unmodified lines | |||
| 43 | 43 | ||
| 44 | #include <linux/io.h> | 44 | #include <linux/io.h> |
| 45 | #include <linux/pci.h> | 45 | #include <linux/pci.h> |
| 46 | #include <linux/vmalloc.h> | ||
| 46 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
| 47 | 48 | ||
| 48 | #include "ipath_kernel.h" | 49 | #include "ipath_kernel.h" |
| @@ -101,7 +101,7 @@ config MTD_REDBOOT_PARTS_READONLY · 100 unmodified lines | |||
| 101 | 101 | ||
| 102 | config MTD_CMDLINE_PARTS | 102 | config MTD_CMDLINE_PARTS |
| 103 | bool "Command line partition table parsing" | 103 | bool "Command line partition table parsing" |
| 104 | depends on MTD_PARTITIONS = "y" | 104 | depends on MTD_PARTITIONS = "y" && MTD = "y" |
| 105 | ---help--- | 105 | ---help--- |
| 106 | Allow generic configuration of the MTD partition tables via the kernel | 106 | Allow generic configuration of the MTD partition tables via the kernel |
| 107 | command line. Multiple flash resources are supported for hardware where | 107 | command line. Multiple flash resources are supported for hardware where |
| @@ -264,7 +264,7 @@ config RFD_FTL · 156 unmodified lines | |||
| 264 | http://www.gensw.com/pages/prod/bios/rfd.htm | 264 | http://www.gensw.com/pages/prod/bios/rfd.htm |
| 265 | 265 | ||
| 266 | config SSFDC | 266 | config SSFDC |
| 267 | bool "NAND SSFDC (SmartMedia) read only translation layer" | 267 | tristate "NAND SSFDC (SmartMedia) read only translation layer" |
| 268 | depends on MTD | 268 | depends on MTD |
| 269 | default n | 269 | default n |
| 270 | help | 270 | help |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/config.h> | ||
| 14 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 15 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 16 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| @@ -29,7 +28,7 @@ struct ssfdcr_record { · 12 unmodified lines | |||
| 29 | int cis_block; /* block n. containing CIS/IDI */ | 28 | int cis_block; /* block n. containing CIS/IDI */ |
| 30 | int erase_size; /* phys_block_size */ | 29 | int erase_size; /* phys_block_size */ |
| 31 | unsigned short *logic_block_map; /* all zones (max 8192 phys blocks on | 30 | unsigned short *logic_block_map; /* all zones (max 8192 phys blocks on |
| 32 | the 128MB) */ | 31 | the 128MiB) */ |
| 33 | int map_len; /* n. phys_blocks on the card */ | 32 | int map_len; /* n. phys_blocks on the card */ |
| 34 | }; | 33 | }; |
| 35 | 34 | ||
| @@ -43,11 +42,11 @@ struct ssfdcr_record { · 7 unmodified lines | |||
| 43 | #define MAX_LOGIC_BLK_PER_ZONE 1000 | 42 | #define MAX_LOGIC_BLK_PER_ZONE 1000 |
| 44 | #define MAX_PHYS_BLK_PER_ZONE 1024 | 43 | #define MAX_PHYS_BLK_PER_ZONE 1024 |
| 45 | 44 | ||
| 46 | #define KB(x) ( (x) * 1024L ) | 45 | #define KiB(x) ( (x) * 1024L ) |
| 47 | #define MB(x) ( KB(x) * 1024L ) | 46 | #define MiB(x) ( KiB(x) * 1024L ) |
| 48 | 47 | ||
| 49 | /** CHS Table | 48 | /** CHS Table |
| 50 | 1MB 2MB 4MB 8MB 16MB 32MB 64MB 128MB | 49 | 1MiB 2MiB 4MiB 8MiB 16MiB 32MiB 64MiB 128MiB |
| 51 | NCylinder 125 125 250 250 500 500 500 500 | 50 | NCylinder 125 125 250 250 500 500 500 500 |
| 52 | NHead 4 4 4 4 4 8 8 16 | 51 | NHead 4 4 4 4 4 8 8 16 |
| 53 | NSector 4 8 8 16 16 16 32 32 | 52 | NSector 4 8 8 16 16 16 32 32 |
| @@ -64,14 +63,14 @@ typedef struct { · 10 unmodified lines | |||
| 64 | 63 | ||
| 65 | /* Must be ordered by size */ | 64 | /* Must be ordered by size */ |
| 66 | static const chs_entry_t chs_table[] = { | 65 | static const chs_entry_t chs_table[] = { |
| 67 | { MB( 1), 125, 4, 4 }, | 66 | { MiB( 1), 125, 4, 4 }, |
| 68 | { MB( 2), 125, 4, 8 }, | 67 | { MiB( 2), 125, 4, 8 }, |
| 69 | { MB( 4), 250, 4, 8 }, | 68 | { MiB( 4), 250, 4, 8 }, |
| 70 | { MB( 8), 250, 4, 16 }, | 69 | { MiB( 8), 250, 4, 16 }, |
| 71 | { MB( 16), 500, 4, 16 }, | 70 | { MiB( 16), 500, 4, 16 }, |
| 72 | { MB( 32), 500, 8, 16 }, | 71 | { MiB( 32), 500, 8, 16 }, |
| 73 | { MB( 64), 500, 8, 32 }, | 72 | { MiB( 64), 500, 8, 32 }, |
| 74 | { MB(128), 500, 16, 32 }, | 73 | { MiB(128), 500, 16, 32 }, |
| 75 | { 0 }, | 74 | { 0 }, |
| 76 | }; | 75 | }; |
| 77 | 76 | ||
| @@ -109,25 +108,30 @@ static int get_valid_cis_sector(struct mtd_info *mtd) · 31 unmodified lines | |||
| 109 | int ret, k, cis_sector; | 108 | int ret, k, cis_sector; |
| 110 | size_t retlen; | 109 | size_t retlen; |
| 111 | loff_t offset; | 110 | loff_t offset; |
| 112 | uint8_t sect_buf[SECTOR_SIZE]; | 111 | uint8_t *sect_buf; |
| 112 | |||
| 113 | cis_sector = -1; | ||
| 114 | |||
| 115 | sect_buf = kmalloc(SECTOR_SIZE, GFP_KERNEL); | ||
| 116 | if (!sect_buf) | ||
| 117 | goto out; | ||
| 113 | 118 | ||
| 114 | /* | 119 | /* |
| 115 | * Look for CIS/IDI sector on the first GOOD block (give up after 4 bad | 120 | * Look for CIS/IDI sector on the first GOOD block (give up after 4 bad |
| 116 | * blocks). If the first good block doesn't contain CIS number the flash | 121 | * blocks). If the first good block doesn't contain CIS number the flash |
| 117 | * is not SSFDC formatted | 122 | * is not SSFDC formatted |
| 118 | */ | 123 | */ |
| 119 | cis_sector = -1; | ||
| 120 | for (k = 0, offset = 0; k < 4; k++, offset += mtd->erasesize) { | 124 | for (k = 0, offset = 0; k < 4; k++, offset += mtd->erasesize) { |
| 121 | if (!mtd->block_isbad(mtd, offset)) { | 125 | if (!mtd->block_isbad(mtd, offset)) { |
| 122 | ret = mtd->read(mtd, offset, SECTOR_SIZE, &retlen, | 126 | ret = mtd->read(mtd, offset, SECTOR_SIZE, &retlen, |
| 123 | sect_buf); | 127 | sect_buf); |
| 124 | 128 | ||
| 125 | /* CIS pattern match on the sector buffer */ | 129 | /* CIS pattern match on the sector buffer */ |
| 126 | if ( ret < 0 || retlen != SECTOR_SIZE ) { | 130 | if (ret < 0 || retlen != SECTOR_SIZE) { |
| 127 | printk(KERN_WARNING | 131 | printk(KERN_WARNING |
| 128 | "SSFDC_RO:can't read CIS/IDI sector\n"); | 132 | "SSFDC_RO:can't read CIS/IDI sector\n"); |
| 129 | } else if ( !memcmp(sect_buf, cis_numbers, | 133 | } else if (!memcmp(sect_buf, cis_numbers, |
| 130 | sizeof(cis_numbers)) ) { | 134 | sizeof(cis_numbers))) { |
| 131 | /* Found */ | 135 | /* Found */ |
| 132 | cis_sector = (int)(offset >> SECTOR_SHIFT); | 136 | cis_sector = (int)(offset >> SECTOR_SHIFT); |
| 133 | } else { | 137 | } else { |
| @@ -140,6 +144,8 @@ static int get_valid_cis_sector(struct mtd_info *mtd) · 6 unmodified lines | |||
| 140 | } | 144 | } |
| 141 | } | 145 | } |
| 142 | 146 | ||
| 147 | kfree(sect_buf); | ||
| 148 | out: | ||
| 143 | return cis_sector; | 149 | return cis_sector; |
| 144 | } | 150 | } |
| 145 | 151 | ||
| @@ -227,7 +233,7 @@ static int get_logical_address(uint8_t *oob_buf) · 81 unmodified lines | |||
| 227 | } | 233 | } |
| 228 | } | 234 | } |
| 229 | 235 | ||
| 230 | if ( !ok ) | 236 | if (!ok) |
| 231 | block_address = -2; | 237 | block_address = -2; |
| 232 | 238 | ||
| 233 | DEBUG(MTD_DEBUG_LEVEL3, "SSFDC_RO: get_logical_address() %d\n", | 239 | DEBUG(MTD_DEBUG_LEVEL3, "SSFDC_RO: get_logical_address() %d\n", |
| @@ -245,8 +251,8 @@ static int build_logical_block_map(struct ssfdcr_record *ssfdc) · 11 unmodified lines | |||
| 245 | struct mtd_info *mtd = ssfdc->mbd.mtd; | 251 | struct mtd_info *mtd = ssfdc->mbd.mtd; |
| 246 | 252 | ||
| 247 | DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: build_block_map() nblks=%d (%luK)\n", | 253 | DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: build_block_map() nblks=%d (%luK)\n", |
| 248 | ssfdc->map_len, (unsigned long)ssfdc->map_len * | 254 | ssfdc->map_len, |
| 249 | ssfdc->erase_size / 1024 ); | 255 | (unsigned long)ssfdc->map_len * ssfdc->erase_size / 1024); |
| 250 | 256 | ||
| 251 | /* Scan every physical block, skip CIS block */ | 257 | /* Scan every physical block, skip CIS block */ |
| 252 | for (phys_block = ssfdc->cis_block + 1; phys_block < ssfdc->map_len; | 258 | for (phys_block = ssfdc->cis_block + 1; phys_block < ssfdc->map_len; |
| @@ -323,21 +329,21 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) · 70 unmodified lines | |||
| 323 | /* Set geometry */ | 329 | /* Set geometry */ |
| 324 | ssfdc->heads = 16; | 330 | ssfdc->heads = 16; |
| 325 | ssfdc->sectors = 32; | 331 | ssfdc->sectors = 32; |
| 326 | get_chs( mtd->size, NULL, &ssfdc->heads, &ssfdc->sectors); | 332 | get_chs(mtd->size, NULL, &ssfdc->heads, &ssfdc->sectors); |
| 327 | ssfdc->cylinders = (unsigned short)((mtd->size >> SECTOR_SHIFT) / | 333 | ssfdc->cylinders = (unsigned short)((mtd->size >> SECTOR_SHIFT) / |
| 328 | ((long)ssfdc->sectors * (long)ssfdc->heads)); | 334 | ((long)ssfdc->sectors * (long)ssfdc->heads)); |
| 329 | 335 | ||
| 330 | DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: using C:%d H:%d S:%d == %ld sects\n", | 336 | DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: using C:%d H:%d S:%d == %ld sects\n", |
| 331 | ssfdc->cylinders, ssfdc->heads , ssfdc->sectors, | 337 | ssfdc->cylinders, ssfdc->heads , ssfdc->sectors, |
| 332 | (long)ssfdc->cylinders * (long)ssfdc->heads * | 338 | (long)ssfdc->cylinders * (long)ssfdc->heads * |
| 333 | (long)ssfdc->sectors ); | 339 | (long)ssfdc->sectors); |
| 334 | 340 | ||
| 335 | ssfdc->mbd.size = (long)ssfdc->heads * (long)ssfdc->cylinders * | 341 | ssfdc->mbd.size = (long)ssfdc->heads * (long)ssfdc->cylinders * |
| 336 | (long)ssfdc->sectors; | 342 | (long)ssfdc->sectors; |
| 337 | 343 | ||
| 338 | /* Allocate logical block map */ | 344 | /* Allocate logical block map */ |
| 339 | ssfdc->logic_block_map = kmalloc( sizeof(ssfdc->logic_block_map[0]) * | 345 | ssfdc->logic_block_map = kmalloc(sizeof(ssfdc->logic_block_map[0]) * |
| 340 | ssfdc->map_len, GFP_KERNEL); | 346 | ssfdc->map_len, GFP_KERNEL); |
| 341 | if (!ssfdc->logic_block_map) { | 347 | if (!ssfdc->logic_block_map) { |
| 342 | printk(KERN_WARNING | 348 | printk(KERN_WARNING |
| 343 | "SSFDC_RO: out of memory for data structures\n"); | 349 | "SSFDC_RO: out of memory for data structures\n"); |
| @@ -408,7 +414,7 @@ static int ssfdcr_readsect(struct mtd_blktrans_dev *dev, · 64 unmodified lines | |||
| 408 | "SSFDC_RO: ssfdcr_readsect() phys_sect_no=%lu\n", | 414 | "SSFDC_RO: ssfdcr_readsect() phys_sect_no=%lu\n", |
| 409 | sect_no); | 415 | sect_no); |
| 410 | 416 | ||
| 411 | if (read_physical_sector( ssfdc->mbd.mtd, buf, sect_no ) < 0) | 417 | if (read_physical_sector(ssfdc->mbd.mtd, buf, sect_no) < 0) |
| 412 | return -EIO; | 418 | return -EIO; |
| 413 | } else { | 419 | } else { |
| 414 | memset(buf, 0xff, SECTOR_SIZE); | 420 | memset(buf, 0xff, SECTOR_SIZE); |
| @@ -2077,7 +2077,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) · 2076 unmodified lines | |||
| 2077 | 2077 | ||
| 2078 | vp->tx_ring[entry].next = 0; | 2078 | vp->tx_ring[entry].next = 0; |
| 2079 | #if DO_ZEROCOPY | 2079 | #if DO_ZEROCOPY |
| 2080 | if (skb->ip_summed != CHECKSUM_HW) | 2080 | if (skb->ip_summed != CHECKSUM_PARTIAL) |
| 2081 | vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded); | 2081 | vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded); |
| 2082 | else | 2082 | else |
| 2083 | vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded | AddTCPChksum | AddUDPChksum); | 2083 | vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded | AddTCPChksum | AddUDPChksum); |
| @@ -813,7 +813,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) · 812 unmodified lines | |||
| 813 | 813 | ||
| 814 | if (mss) | 814 | if (mss) |
| 815 | flags |= LargeSend | ((mss & MSSMask) << MSSShift); | 815 | flags |= LargeSend | ((mss & MSSMask) << MSSShift); |
| 816 | else if (skb->ip_summed == CHECKSUM_HW) { | 816 | else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 817 | const struct iphdr *ip = skb->nh.iph; | 817 | const struct iphdr *ip = skb->nh.iph; |
| 818 | if (ip->protocol == IPPROTO_TCP) | 818 | if (ip->protocol == IPPROTO_TCP) |
| 819 | flags |= IPCS | TCPCS; | 819 | flags |= IPCS | TCPCS; |
| @@ -867,7 +867,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) · 47 unmodified lines | |||
| 867 | if (mss) | 867 | if (mss) |
| 868 | ctrl |= LargeSend | | 868 | ctrl |= LargeSend | |
| 869 | ((mss & MSSMask) << MSSShift); | 869 | ((mss & MSSMask) << MSSShift); |
| 870 | else if (skb->ip_summed == CHECKSUM_HW) { | 870 | else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 871 | if (ip->protocol == IPPROTO_TCP) | 871 | if (ip->protocol == IPPROTO_TCP) |
| 872 | ctrl |= IPCS | TCPCS; | 872 | ctrl |= IPCS | TCPCS; |
| 873 | else if (ip->protocol == IPPROTO_UDP) | 873 | else if (ip->protocol == IPPROTO_UDP) |
| @@ -898,7 +898,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) · 24 unmodified lines | |||
| 898 | txd->addr = cpu_to_le64(first_mapping); | 898 | txd->addr = cpu_to_le64(first_mapping); |
| 899 | wmb(); | 899 | wmb(); |
| 900 | 900 | ||
| 901 | if (skb->ip_summed == CHECKSUM_HW) { | 901 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 902 | if (ip->protocol == IPPROTO_TCP) | 902 | if (ip->protocol == IPPROTO_TCP) |
| 903 | txd->opts1 = cpu_to_le32(first_eor | first_len | | 903 | txd->opts1 = cpu_to_le32(first_eor | first_len | |
| 904 | FirstFrag | DescOwn | | 904 | FirstFrag | DescOwn | |
| @@ -2040,7 +2040,7 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm) · 2039 unmodified lines | |||
| 2040 | */ | 2040 | */ |
| 2041 | if (bd_flags & BD_FLG_TCP_UDP_SUM) { | 2041 | if (bd_flags & BD_FLG_TCP_UDP_SUM) { |
| 2042 | skb->csum = htons(csum); | 2042 | skb->csum = htons(csum); |
| 2043 | skb->ip_summed = CHECKSUM_HW; | 2043 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 2044 | } else { | 2044 | } else { |
| 2045 | skb->ip_summed = CHECKSUM_NONE; | 2045 | skb->ip_summed = CHECKSUM_NONE; |
| 2046 | } | 2046 | } |
| @@ -2511,7 +2511,7 @@ restart: · 464 unmodified lines | |||
| 2511 | 2511 | ||
| 2512 | mapping = ace_map_tx_skb(ap, skb, skb, idx); | 2512 | mapping = ace_map_tx_skb(ap, skb, skb, idx); |
| 2513 | flagsize = (skb->len << 16) | (BD_FLG_END); | 2513 | flagsize = (skb->len << 16) | (BD_FLG_END); |
| 2514 | if (skb->ip_summed == CHECKSUM_HW) | 2514 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
| 2515 | flagsize |= BD_FLG_TCP_UDP_SUM; | 2515 | flagsize |= BD_FLG_TCP_UDP_SUM; |
| 2516 | #if ACENIC_DO_VLAN | 2516 | #if ACENIC_DO_VLAN |
| 2517 | if (vlan_tx_tag_present(skb)) { | 2517 | if (vlan_tx_tag_present(skb)) { |
| @@ -2534,7 +2534,7 @@ restart: · 16 unmodified lines | |||
| 2534 | 2534 | ||
| 2535 | mapping = ace_map_tx_skb(ap, skb, NULL, idx); | 2535 | mapping = ace_map_tx_skb(ap, skb, NULL, idx); |
| 2536 | flagsize = (skb_headlen(skb) << 16); | 2536 | flagsize = (skb_headlen(skb) << 16); |
| 2537 | if (skb->ip_summed == CHECKSUM_HW) | 2537 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
| 2538 | flagsize |= BD_FLG_TCP_UDP_SUM; | 2538 | flagsize |= BD_FLG_TCP_UDP_SUM; |
| 2539 | #if ACENIC_DO_VLAN | 2539 | #if ACENIC_DO_VLAN |
| 2540 | if (vlan_tx_tag_present(skb)) { | 2540 | if (vlan_tx_tag_present(skb)) { |
| @@ -2560,7 +2560,7 @@ restart: · 19 unmodified lines | |||
| 2560 | PCI_DMA_TODEVICE); | 2560 | PCI_DMA_TODEVICE); |
| 2561 | 2561 | ||
| 2562 | flagsize = (frag->size << 16); | 2562 | flagsize = (frag->size << 16); |
| 2563 | if (skb->ip_summed == CHECKSUM_HW) | 2563 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
| 2564 | flagsize |= BD_FLG_TCP_UDP_SUM; | 2564 | flagsize |= BD_FLG_TCP_UDP_SUM; |
| 2565 | idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap); | 2565 | idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap); |
| 2566 | 2566 | ||
| @@ -161,6 +161,7 @@ static struct pci_device_id com20020pci_id_table[] = { · 160 unmodified lines | |||
| 161 | { 0x1571, 0xa204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, | 161 | { 0x1571, 0xa204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, |
| 162 | { 0x1571, 0xa205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, | 162 | { 0x1571, 0xa205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, |
| 163 | { 0x1571, 0xa206, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, | 163 | { 0x1571, 0xa206, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, |
| 164 | { 0x10B5, 0x9030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, | ||
| 164 | { 0x10B5, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, | 165 | { 0x10B5, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, |
| 165 | {0,} | 166 | {0,} |
| 166 | }; | 167 | }; |
| @@ -4423,7 +4423,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) · 4422 unmodified lines | |||
| 4423 | ring_prod = TX_RING_IDX(prod); | 4423 | ring_prod = TX_RING_IDX(prod); |
| 4424 | 4424 | ||
| 4425 | vlan_tag_flags = 0; | 4425 | vlan_tag_flags = 0; |
| 4426 | if (skb->ip_summed == CHECKSUM_HW) { | 4426 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 4427 | vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM; | 4427 | vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM; |
| 4428 | } | 4428 | } |
| 4429 | 4429 | ||
| @@ -2167,7 +2167,7 @@ end_copy_pkt: · 2166 unmodified lines | |||
| 2167 | cas_page_unmap(addr); | 2167 | cas_page_unmap(addr); |
| 2168 | } | 2168 | } |
| 2169 | skb->csum = ntohs(i ^ 0xffff); | 2169 | skb->csum = ntohs(i ^ 0xffff); |
| 2170 | skb->ip_summed = CHECKSUM_HW; | 2170 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 2171 | skb->protocol = eth_type_trans(skb, cp->dev); | 2171 | skb->protocol = eth_type_trans(skb, cp->dev); |
| 2172 | return len; | 2172 | return len; |
| 2173 | } | 2173 | } |
| @@ -2821,7 +2821,7 @@ static inline int cas_xmit_tx_ringN(struct cas *cp, int ring, · 647 unmodified lines | |||
| 2821 | } | 2821 | } |
| 2822 | 2822 | ||
| 2823 | ctrl = 0; | 2823 | ctrl = 0; |
| 2824 | if (skb->ip_summed == CHECKSUM_HW) { | 2824 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 2825 | u64 csum_start_off, csum_stuff_off; | 2825 | u64 csum_start_off, csum_stuff_off; |
| 2826 | 2826 | ||
| 2827 | csum_start_off = (u64) (skb->h.raw - skb->data); | 2827 | csum_start_off = (u64) (skb->h.raw - skb->data); |
| @@ -1470,9 +1470,9 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) · 1469 unmodified lines | |||
| 1470 | } | 1470 | } |
| 1471 | 1471 | ||
| 1472 | if (!(adapter->flags & UDP_CSUM_CAPABLE) && | 1472 | if (!(adapter->flags & UDP_CSUM_CAPABLE) && |
| 1473 | skb->ip_summed == CHECKSUM_HW && | 1473 | skb->ip_summed == CHECKSUM_PARTIAL && |
| 1474 | skb->nh.iph->protocol == IPPROTO_UDP) | 1474 | skb->nh.iph->protocol == IPPROTO_UDP) |
| 1475 | if (unlikely(skb_checksum_help(skb, 0))) { | 1475 | if (unlikely(skb_checksum_help(skb))) { |
| 1476 | dev_kfree_skb_any(skb); | 1476 | dev_kfree_skb_any(skb); |
| 1477 | return NETDEV_TX_OK; | 1477 | return NETDEV_TX_OK; |
| 1478 | } | 1478 | } |
| @@ -1495,11 +1495,11 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) · 16 unmodified lines | |||
| 1495 | cpl = (struct cpl_tx_pkt *)__skb_push(skb, sizeof(*cpl)); | 1495 | cpl = (struct cpl_tx_pkt *)__skb_push(skb, sizeof(*cpl)); |
| 1496 | cpl->opcode = CPL_TX_PKT; | 1496 | cpl->opcode = CPL_TX_PKT; |
| 1497 | cpl->ip_csum_dis = 1; /* SW calculates IP csum */ | 1497 | cpl->ip_csum_dis = 1; /* SW calculates IP csum */ |
| 1498 | cpl->l4_csum_dis = skb->ip_summed == CHECKSUM_HW ? 0 : 1; | 1498 | cpl->l4_csum_dis = skb->ip_summed == CHECKSUM_PARTIAL ? 0 : 1; |
| 1499 | /* the length field isn't used so don't bother setting it */ | 1499 | /* the length field isn't used so don't bother setting it */ |
| 1500 | 1500 | ||
| 1501 | st->tx_cso += (skb->ip_summed == CHECKSUM_HW); | 1501 | st->tx_cso += (skb->ip_summed == CHECKSUM_PARTIAL); |
| 1502 | sge->stats.tx_do_cksum += (skb->ip_summed == CHECKSUM_HW); | 1502 | sge->stats.tx_do_cksum += (skb->ip_summed == CHECKSUM_PARTIAL); |
| 1503 | sge->stats.tx_reg_pkts++; | 1503 | sge->stats.tx_reg_pkts++; |
| 1504 | } | 1504 | } |
| 1505 | cpl->iff = dev->if_port; | 1505 | cpl->iff = dev->if_port; |
| @@ -611,7 +611,7 @@ start_xmit (struct sk_buff *skb, struct net_device *dev) · 610 unmodified lines | |||
| 611 | txdesc = &np->tx_ring[entry]; | 611 | txdesc = &np->tx_ring[entry]; |
| 612 | 612 | ||
| 613 | #if 0 | 613 | #if 0 |
| 614 | if (skb->ip_summed == CHECKSUM_HW) { | 614 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 615 | txdesc->status |= | 615 | txdesc->status |= |
| 616 | cpu_to_le64 (TCPChecksumEnable | UDPChecksumEnable | | 616 | cpu_to_le64 (TCPChecksumEnable | UDPChecksumEnable | |
| 617 | IPChecksumEnable); | 617 | IPChecksumEnable); |
| @@ -2600,7 +2600,7 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, · 2599 unmodified lines | |||
| 2600 | unsigned int i; | 2600 | unsigned int i; |
| 2601 | uint8_t css; | 2601 | uint8_t css; |
| 2602 | 2602 | ||
| 2603 | if (likely(skb->ip_summed == CHECKSUM_HW)) { | 2603 | if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { |
| 2604 | css = skb->h.raw - skb->data; | 2604 | css = skb->h.raw - skb->data; |
| 2605 | 2605 | ||
| 2606 | i = tx_ring->next_to_use; | 2606 | i = tx_ring->next_to_use; |
| @@ -2927,11 +2927,11 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) · 320 unmodified lines | |||
| 2927 | } | 2927 | } |
| 2928 | 2928 | ||
| 2929 | /* reserve a descriptor for the offload context */ | 2929 | /* reserve a descriptor for the offload context */ |
| 2930 | if ((mss) || (skb->ip_summed == CHECKSUM_HW)) | 2930 | if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL)) |
| 2931 | count++; | 2931 | count++; |
| 2932 | count++; | 2932 | count++; |
| 2933 | #else | 2933 | #else |
| 2934 | if (skb->ip_summed == CHECKSUM_HW) | 2934 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
| 2935 | count++; | 2935 | count++; |
| 2936 | #endif | 2936 | #endif |
| 2937 | 2937 | ||
| @@ -3608,7 +3608,7 @@ e1000_rx_checksum(struct e1000_adapter *adapter, · 670 unmodified lines | |||
| 3608 | */ | 3608 | */ |
| 3609 | csum = ntohl(csum ^ 0xFFFF); | 3609 | csum = ntohl(csum ^ 0xFFFF); |
| 3610 | skb->csum = csum; | 3610 | skb->csum = csum; |
| 3611 | skb->ip_summed = CHECKSUM_HW; | 3611 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 3612 | } | 3612 | } |
| 3613 | adapter->hw_csum_good++; | 3613 | adapter->hw_csum_good++; |
| 3614 | } | 3614 | } |
| @@ -1503,7 +1503,8 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) · 1502 unmodified lines | |||
| 1503 | tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT); | 1503 | tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT); |
| 1504 | else | 1504 | else |
| 1505 | #endif | 1505 | #endif |
| 1506 | tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0); | 1506 | tx_flags_extra = skb->ip_summed == CHECKSUM_PARTIAL ? |
| 1507 | NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0; | ||
| 1507 | 1508 | ||
| 1508 | /* vlan tag */ | 1509 | /* vlan tag */ |
| 1509 | if (np->vlangrp && vlan_tx_tag_present(skb)) { | 1510 | if (np->vlangrp && vlan_tx_tag_present(skb)) { |
| @@ -947,7 +947,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) · 946 unmodified lines | |||
| 947 | 947 | ||
| 948 | /* Set up checksumming */ | 948 | /* Set up checksumming */ |
| 949 | if (likely((dev->features & NETIF_F_IP_CSUM) | 949 | if (likely((dev->features & NETIF_F_IP_CSUM) |
| 950 | && (CHECKSUM_HW == skb->ip_summed))) { | 950 | && (CHECKSUM_PARTIAL == skb->ip_summed))) { |
| 951 | fcb = gfar_add_fcb(skb, txbdp); | 951 | fcb = gfar_add_fcb(skb, txbdp); |
| 952 | status |= TXBD_TOE; | 952 | status |= TXBD_TOE; |
| 953 | gfar_tx_checksum(skb, fcb); | 953 | gfar_tx_checksum(skb, fcb); |
| @@ -1648,7 +1648,7 @@ static int hamachi_rx(struct net_device *dev) · 1647 unmodified lines | |||
| 1648 | * could do the pseudo myself and return | 1648 | * could do the pseudo myself and return |
| 1649 | * CHECKSUM_UNNECESSARY | 1649 | * CHECKSUM_UNNECESSARY |
| 1650 | */ | 1650 | */ |
| 1651 | skb->ip_summed = CHECKSUM_HW; | 1651 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 1652 | } | 1652 | } |
| 1653 | } | 1653 | } |
| 1654 | } | 1654 | } |
| @@ -1036,7 +1036,7 @@ static inline u16 emac_tx_csum(struct ocp_enet_private *dev, · 1035 unmodified lines | |||
| 1036 | struct sk_buff *skb) | 1036 | struct sk_buff *skb) |
| 1037 | { | 1037 | { |
| 1038 | #if defined(CONFIG_IBM_EMAC_TAH) | 1038 | #if defined(CONFIG_IBM_EMAC_TAH) |
| 1039 | if (skb->ip_summed == CHECKSUM_HW) { | 1039 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1040 | ++dev->stats.tx_packets_csum; | 1040 | ++dev->stats.tx_packets_csum; |
| 1041 | return EMAC_TX_CTRL_TAH_CSUM; | 1041 | return EMAC_TX_CTRL_TAH_CSUM; |
| 1042 | } | 1042 | } |
| @@ -1387,7 +1387,7 @@ static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev) · 1386 unmodified lines | |||
| 1387 | * MAC header which should not be summed and the TCP/UDP pseudo headers | 1387 | * MAC header which should not be summed and the TCP/UDP pseudo headers |
| 1388 | * manually. | 1388 | * manually. |
| 1389 | */ | 1389 | */ |
| 1390 | if (skb->ip_summed == CHECKSUM_HW) { | 1390 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1391 | int proto = ntohs(skb->nh.iph->protocol); | 1391 | int proto = ntohs(skb->nh.iph->protocol); |
| 1392 | unsigned int csoff; | 1392 | unsigned int csoff; |
| 1393 | struct iphdr *ih = skb->nh.iph; | 1393 | struct iphdr *ih = skb->nh.iph; |
| @@ -249,7 +249,7 @@ static void __exit ali_ircc_cleanup(void) · 248 unmodified lines | |||
| 249 | 249 | ||
| 250 | IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); | 250 | IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); |
| 251 | 251 | ||
| 252 | for (i=0; i < 4; i++) { | 252 | for (i=0; i < ARRAY_SIZE(dev_self); i++) { |
| 253 | if (dev_self[i]) | 253 | if (dev_self[i]) |
| 254 | ali_ircc_close(dev_self[i]); | 254 | ali_ircc_close(dev_self[i]); |
| 255 | } | 255 | } |
| @@ -273,6 +273,12 @@ static int ali_ircc_open(int i, chipio_t *info) · 17 unmodified lines | |||
| 273 | int err; | 273 | int err; |
| 274 | 274 | ||
| 275 | IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); | 275 | IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); |
| 276 | |||
| 277 | if (i >= ARRAY_SIZE(dev_self)) { | ||
| 278 | IRDA_ERROR("%s(), maximum number of supported chips reached!\n", | ||
| 279 | __FUNCTION__); | ||
| 280 | return -ENOMEM; | ||
| 281 | } | ||
| 276 | 282 | ||
| 277 | /* Set FIR FIFO and DMA Threshold */ | 283 | /* Set FIR FIFO and DMA Threshold */ |
| 278 | if ((ali_ircc_setup(info)) == -1) | 284 | if ((ali_ircc_setup(info)) == -1) |
| @@ -1090,7 +1090,7 @@ static int __init irport_init(void) · 1089 unmodified lines | |||
| 1090 | { | 1090 | { |
| 1091 | int i; | 1091 | int i; |
| 1092 | 1092 | ||
| 1093 | for (i=0; (io[i] < 2000) && (i < 4); i++) { | 1093 | for (i=0; (io[i] < 2000) && (i < ARRAY_SIZE(dev_self)); i++) { |
| 1094 | if (irport_open(i, io[i], irq[i]) != NULL) | 1094 | if (irport_open(i, io[i], irq[i]) != NULL) |
| 1095 | return 0; | 1095 | return 0; |
| 1096 | } | 1096 | } |
| @@ -1112,7 +1112,7 @@ static void __exit irport_cleanup(void) · 15 unmodified lines | |||
| 1112 | 1112 | ||
| 1113 | IRDA_DEBUG( 4, "%s()\n", __FUNCTION__); | 1113 | IRDA_DEBUG( 4, "%s()\n", __FUNCTION__); |
| 1114 | 1114 | ||
| 1115 | for (i=0; i < 4; i++) { | 1115 | for (i=0; i < ARRAY_SIZE(dev_self); i++) { |
| 1116 | if (dev_self[i]) | 1116 | if (dev_self[i]) |
| 1117 | irport_close(dev_self[i]); | 1117 | irport_close(dev_self[i]); |
| 1118 | } | 1118 | } |
| @@ -279,7 +279,7 @@ static void via_ircc_clean(void) · 278 unmodified lines | |||
| 279 | 279 | ||
| 280 | IRDA_DEBUG(3, "%s()\n", __FUNCTION__); | 280 | IRDA_DEBUG(3, "%s()\n", __FUNCTION__); |
| 281 | 281 | ||
| 282 | for (i=0; i < 4; i++) { | 282 | for (i=0; i < ARRAY_SIZE(dev_self); i++) { |
| 283 | if (dev_self[i]) | 283 | if (dev_self[i]) |
| 284 | via_ircc_close(dev_self[i]); | 284 | via_ircc_close(dev_self[i]); |
| 285 | } | 285 | } |
| @@ -327,6 +327,9 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) · 41 unmodified lines | |||
| 327 | 327 | ||
| 328 | IRDA_DEBUG(3, "%s()\n", __FUNCTION__); | 328 | IRDA_DEBUG(3, "%s()\n", __FUNCTION__); |
| 329 | 329 | ||
| 330 | if (i >= ARRAY_SIZE(dev_self)) | ||
| 331 | return -ENOMEM; | ||
| 332 | |||
| 330 | /* Allocate new instance of the driver */ | 333 | /* Allocate new instance of the driver */ |
| 331 | dev = alloc_irdadev(sizeof(struct via_ircc_cb)); | 334 | dev = alloc_irdadev(sizeof(struct via_ircc_cb)); |
| 332 | if (dev == NULL) | 335 | if (dev == NULL) |
| @@ -117,7 +117,7 @@ static int __init w83977af_init(void) · 116 unmodified lines | |||
| 117 | 117 | ||
| 118 | IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); | 118 | IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); |
| 119 | 119 | ||
| 120 | for (i=0; (io[i] < 2000) && (i < 4); i++) { | 120 | for (i=0; (io[i] < 2000) && (i < ARRAY_SIZE(dev_self)); i++) { |
| 121 | if (w83977af_open(i, io[i], irq[i], dma[i]) == 0) | 121 | if (w83977af_open(i, io[i], irq[i], dma[i]) == 0) |
| 122 | return 0; | 122 | return 0; |
| 123 | } | 123 | } |
| @@ -136,7 +136,7 @@ static void __exit w83977af_cleanup(void) · 12 unmodified lines | |||
| 136 | 136 | ||
| 137 | IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); | 137 | IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); |
| 138 | 138 | ||
| 139 | for (i=0; i < 4; i++) { | 139 | for (i=0; i < ARRAY_SIZE(dev_self); i++) { |
| 140 | if (dev_self[i]) | 140 | if (dev_self[i]) |
| 141 | w83977af_close(dev_self[i]); | 141 | w83977af_close(dev_self[i]); |
| 142 | } | 142 | } |
| @@ -1232,7 +1232,7 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb) · 1231 unmodified lines | |||
| 1232 | unsigned int i; | 1232 | unsigned int i; |
| 1233 | uint8_t css, cso; | 1233 | uint8_t css, cso; |
| 1234 | 1234 | ||
| 1235 | if(likely(skb->ip_summed == CHECKSUM_HW)) { | 1235 | if(likely(skb->ip_summed == CHECKSUM_PARTIAL)) { |
| 1236 | css = skb->h.raw - skb->data; | 1236 | css = skb->h.raw - skb->data; |
| 1237 | cso = (skb->h.raw + skb->csum) - skb->data; | 1237 | cso = (skb->h.raw + skb->csum) - skb->data; |
| 1238 | 1238 | ||
| @@ -1147,7 +1147,7 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp, · 1146 unmodified lines | |||
| 1147 | desc->byte_cnt = length; | 1147 | desc->byte_cnt = length; |
| 1148 | desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); | 1148 | desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); |
| 1149 | 1149 | ||
| 1150 | if (skb->ip_summed == CHECKSUM_HW) { | 1150 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1151 | BUG_ON(skb->protocol != ETH_P_IP); | 1151 | BUG_ON(skb->protocol != ETH_P_IP); |
| 1152 | 1152 | ||
| 1153 | cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM | | 1153 | cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM | |
| @@ -930,7 +930,7 @@ static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, u16 hw_csum) · 929 unmodified lines | |||
| 930 | (vh->h_vlan_encapsulated_proto == htons(ETH_P_IP) || | 930 | (vh->h_vlan_encapsulated_proto == htons(ETH_P_IP) || |
| 931 | vh->h_vlan_encapsulated_proto == htons(ETH_P_IPV6))) { | 931 | vh->h_vlan_encapsulated_proto == htons(ETH_P_IPV6))) { |
| 932 | skb->csum = hw_csum; | 932 | skb->csum = hw_csum; |
| 933 | skb->ip_summed = CHECKSUM_HW; | 933 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 934 | } | 934 | } |
| 935 | } | 935 | } |
| 936 | 936 | ||
| @@ -973,7 +973,7 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, · 36 unmodified lines | |||
| 973 | if ((skb->protocol == ntohs(ETH_P_IP)) || | 973 | if ((skb->protocol == ntohs(ETH_P_IP)) || |
| 974 | (skb->protocol == ntohs(ETH_P_IPV6))) { | 974 | (skb->protocol == ntohs(ETH_P_IPV6))) { |
| 975 | skb->csum = ntohs((u16) csum); | 975 | skb->csum = ntohs((u16) csum); |
| 976 | skb->ip_summed = CHECKSUM_HW; | 976 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 977 | } else | 977 | } else |
| 978 | myri10ge_vlan_ip_csum(skb, ntohs((u16) csum)); | 978 | myri10ge_vlan_ip_csum(skb, ntohs((u16) csum)); |
| 979 | } | 979 | } |
| @@ -1897,13 +1897,13 @@ again: · 917 unmodified lines | |||
| 1897 | pseudo_hdr_offset = 0; | 1897 | pseudo_hdr_offset = 0; |
| 1898 | odd_flag = 0; | 1898 | odd_flag = 0; |
| 1899 | flags = (MXGEFW_FLAGS_NO_TSO | MXGEFW_FLAGS_FIRST); | 1899 | flags = (MXGEFW_FLAGS_NO_TSO | MXGEFW_FLAGS_FIRST); |
| 1900 | if (likely(skb->ip_summed == CHECKSUM_HW)) { | 1900 | if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { |
| 1901 | cksum_offset = (skb->h.raw - skb->data); | 1901 | cksum_offset = (skb->h.raw - skb->data); |
| 1902 | pseudo_hdr_offset = (skb->h.raw + skb->csum) - skb->data; | 1902 | pseudo_hdr_offset = (skb->h.raw + skb->csum) - skb->data; |
| 1903 | /* If the headers are excessively large, then we must | 1903 | /* If the headers are excessively large, then we must |
| 1904 | * fall back to a software checksum */ | 1904 | * fall back to a software checksum */ |
| 1905 | if (unlikely(cksum_offset > 255 || pseudo_hdr_offset > 127)) { | 1905 | if (unlikely(cksum_offset > 255 || pseudo_hdr_offset > 127)) { |
| 1906 | if (skb_checksum_help(skb, 0)) | 1906 | if (skb_checksum_help(skb)) |
| 1907 | goto drop; | 1907 | goto drop; |
| 1908 | cksum_offset = 0; | 1908 | cksum_offset = 0; |
| 1909 | pseudo_hdr_offset = 0; | 1909 | pseudo_hdr_offset = 0; |
| @@ -1153,7 +1153,7 @@ again: · 1152 unmodified lines | |||
| 1153 | if (!nr_frags) | 1153 | if (!nr_frags) |
| 1154 | frag = NULL; | 1154 | frag = NULL; |
| 1155 | extsts = 0; | 1155 | extsts = 0; |
| 1156 | if (skb->ip_summed == CHECKSUM_HW) { | 1156 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1157 | extsts |= EXTSTS_IPPKT; | 1157 | extsts |= EXTSTS_IPPKT; |
| 1158 | if (IPPROTO_TCP == skb->nh.iph->protocol) | 1158 | if (IPPROTO_TCP == skb->nh.iph->protocol) |
| 1159 | extsts |= EXTSTS_TCPPKT; | 1159 | extsts |= EXTSTS_TCPPKT; |
| @@ -2169,7 +2169,7 @@ static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) · 2168 unmodified lines | |||
| 2169 | if (mss) | 2169 | if (mss) |
| 2170 | return LargeSend | ((mss & MSSMask) << MSSShift); | 2170 | return LargeSend | ((mss & MSSMask) << MSSShift); |
| 2171 | } | 2171 | } |
| 2172 | if (skb->ip_summed == CHECKSUM_HW) { | 2172 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 2173 | const struct iphdr *ip = skb->nh.iph; | 2173 | const struct iphdr *ip = skb->nh.iph; |
| 2174 | 2174 | ||
| 2175 | if (ip->protocol == IPPROTO_TCP) | 2175 | if (ip->protocol == IPPROTO_TCP) |
| @@ -3893,7 +3893,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) · 3892 unmodified lines | |||
| 3893 | txdp->Control_1 |= TXD_TCP_LSO_MSS(s2io_tcp_mss(skb)); | 3893 | txdp->Control_1 |= TXD_TCP_LSO_MSS(s2io_tcp_mss(skb)); |
| 3894 | } | 3894 | } |
| 3895 | #endif | 3895 | #endif |
| 3896 | if (skb->ip_summed == CHECKSUM_HW) { | 3896 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 3897 | txdp->Control_2 |= | 3897 | txdp->Control_2 |= |
| 3898 | (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN | | 3898 | (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN | |
| 3899 | TXD_TX_CKO_UDP_EN); | 3899 | TXD_TX_CKO_UDP_EN); |
| @@ -1559,7 +1559,7 @@ struct sk_buff *pMessage) /* pointer to send-message */ · 1558 unmodified lines | |||
| 1559 | pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); | 1559 | pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); |
| 1560 | pTxd->pMBuf = pMessage; | 1560 | pTxd->pMBuf = pMessage; |
| 1561 | 1561 | ||
| 1562 | if (pMessage->ip_summed == CHECKSUM_HW) { | 1562 | if (pMessage->ip_summed == CHECKSUM_PARTIAL) { |
| 1563 | u16 hdrlen = pMessage->h.raw - pMessage->data; | 1563 | u16 hdrlen = pMessage->h.raw - pMessage->data; |
| 1564 | u16 offset = hdrlen + pMessage->csum; | 1564 | u16 offset = hdrlen + pMessage->csum; |
| 1565 | 1565 | ||
| @@ -1678,7 +1678,7 @@ struct sk_buff *pMessage) /* pointer to send-message */ · 112 unmodified lines | |||
| 1678 | /* | 1678 | /* |
| 1679 | ** Does the HW need to evaluate checksum for TCP or UDP packets? | 1679 | ** Does the HW need to evaluate checksum for TCP or UDP packets? |
| 1680 | */ | 1680 | */ |
| 1681 | if (pMessage->ip_summed == CHECKSUM_HW) { | 1681 | if (pMessage->ip_summed == CHECKSUM_PARTIAL) { |
| 1682 | u16 hdrlen = pMessage->h.raw - pMessage->data; | 1682 | u16 hdrlen = pMessage->h.raw - pMessage->data; |
| 1683 | u16 offset = hdrlen + pMessage->csum; | 1683 | u16 offset = hdrlen + pMessage->csum; |
| 1684 | 1684 | ||
| @@ -2158,7 +2158,7 @@ rx_start: · 473 unmodified lines | |||
| 2158 | 2158 | ||
| 2159 | #ifdef USE_SK_RX_CHECKSUM | 2159 | #ifdef USE_SK_RX_CHECKSUM |
| 2160 | pMsg->csum = pRxd->TcpSums & 0xffff; | 2160 | pMsg->csum = pRxd->TcpSums & 0xffff; |
| 2161 | pMsg->ip_summed = CHECKSUM_HW; | 2161 | pMsg->ip_summed = CHECKSUM_COMPLETE; |
| 2162 | #else | 2162 | #else |
| 2163 | pMsg->ip_summed = CHECKSUM_NONE; | 2163 | pMsg->ip_summed = CHECKSUM_NONE; |
| 2164 | #endif | 2164 | #endif |
| @@ -2338,7 +2338,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) · 2337 unmodified lines | |||
| 2338 | td->dma_lo = map; | 2338 | td->dma_lo = map; |
| 2339 | td->dma_hi = map >> 32; | 2339 | td->dma_hi = map >> 32; |
| 2340 | 2340 | ||
| 2341 | if (skb->ip_summed == CHECKSUM_HW) { | 2341 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 2342 | int offset = skb->h.raw - skb->data; | 2342 | int offset = skb->h.raw - skb->data; |
| 2343 | 2343 | ||
| 2344 | /* This seems backwards, but it is what the sk98lin | 2344 | /* This seems backwards, but it is what the sk98lin |
| @@ -2642,7 +2642,7 @@ static inline struct sk_buff *skge_rx_get(struct skge_port *skge, · 297 unmodified lines | |||
| 2642 | skb->dev = skge->netdev; | 2642 | skb->dev = skge->netdev; |
| 2643 | if (skge->rx_csum) { | 2643 | if (skge->rx_csum) { |
| 2644 | skb->csum = csum; | 2644 | skb->csum = csum; |
| 2645 | skb->ip_summed = CHECKSUM_HW; | 2645 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 2646 | } | 2646 | } |
| 2647 | 2647 | ||
| 2648 | skb->protocol = eth_type_trans(skb, skge->netdev); | 2648 | skb->protocol = eth_type_trans(skb, skge->netdev); |
| @@ -1163,7 +1163,7 @@ static unsigned tx_le_req(const struct sk_buff *skb) · 1162 unmodified lines | |||
| 1163 | if (skb_is_gso(skb)) | 1163 | if (skb_is_gso(skb)) |
| 1164 | ++count; | 1164 | ++count; |
| 1165 | 1165 | ||
| 1166 | if (skb->ip_summed == CHECKSUM_HW) | 1166 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
| 1167 | ++count; | 1167 | ++count; |
| 1168 | 1168 | ||
| 1169 | return count; | 1169 | return count; |
| @@ -1272,7 +1272,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) · 102 unmodified lines | |||
| 1272 | #endif | 1272 | #endif |
| 1273 | 1273 | ||
| 1274 | /* Handle TCP checksum offload */ | 1274 | /* Handle TCP checksum offload */ |
| 1275 | if (skb->ip_summed == CHECKSUM_HW) { | 1275 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1276 | u16 hdr = skb->h.raw - skb->data; | 1276 | u16 hdr = skb->h.raw - skb->data; |
| 1277 | u16 offset = hdr + skb->csum; | 1277 | u16 offset = hdr + skb->csum; |
| 1278 | 1278 | ||
| @@ -2000,7 +2000,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) · 721 unmodified lines | |||
| 2000 | #endif | 2000 | #endif |
| 2001 | case OP_RXCHKS: | 2001 | case OP_RXCHKS: |
| 2002 | skb = sky2->rx_ring[sky2->rx_next].skb; | 2002 | skb = sky2->rx_ring[sky2->rx_next].skb; |
| 2003 | skb->ip_summed = CHECKSUM_HW; | 2003 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 2004 | skb->csum = le16_to_cpu(status); | 2004 | skb->csum = le16_to_cpu(status); |
| 2005 | break; | 2005 | break; |
| 2006 | 2006 | ||
| @@ -1230,7 +1230,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) · 1229 unmodified lines | |||
| 1230 | } | 1230 | } |
| 1231 | 1231 | ||
| 1232 | #if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE) | 1232 | #if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE) |
| 1233 | if (skb->ip_summed == CHECKSUM_HW) { | 1233 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1234 | if (skb_padto(skb, (skb->len + PADDING_MASK) & ~PADDING_MASK)) | 1234 | if (skb_padto(skb, (skb->len + PADDING_MASK) & ~PADDING_MASK)) |
| 1235 | return NETDEV_TX_OK; | 1235 | return NETDEV_TX_OK; |
| 1236 | } | 1236 | } |
| @@ -1252,7 +1252,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) · 15 unmodified lines | |||
| 1252 | status |= TxDescIntr; | 1252 | status |= TxDescIntr; |
| 1253 | np->reap_tx = 0; | 1253 | np->reap_tx = 0; |
| 1254 | } | 1254 | } |
| 1255 | if (skb->ip_summed == CHECKSUM_HW) { | 1255 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1256 | status |= TxCalTCP; | 1256 | status |= TxCalTCP; |
| 1257 | np->stats.tx_compressed++; | 1257 | np->stats.tx_compressed++; |
| 1258 | } | 1258 | } |
| @@ -1499,7 +1499,7 @@ static int __netdev_rx(struct net_device *dev, int *quota) · 240 unmodified lines | |||
| 1499 | * Until then, the printk stays. :-) -Ion | 1499 | * Until then, the printk stays. :-) -Ion |
| 1500 | */ | 1500 | */ |
| 1501 | else if (le16_to_cpu(desc->status2) & 0x0040) { | 1501 | else if (le16_to_cpu(desc->status2) & 0x0040) { |
| 1502 | skb->ip_summed = CHECKSUM_HW; | 1502 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 1503 | skb->csum = le16_to_cpu(desc->csum); | 1503 | skb->csum = le16_to_cpu(desc->csum); |
| 1504 | printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2)); | 1504 | printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2)); |
| 1505 | } | 1505 | } |
| @@ -855,7 +855,7 @@ static int gem_rx(struct gem *gp, int work_to_do) · 854 unmodified lines | |||
| 855 | } | 855 | } |
| 856 | 856 | ||
| 857 | skb->csum = ntohs((status & RXDCTRL_TCPCSUM) ^ 0xffff); | 857 | skb->csum = ntohs((status & RXDCTRL_TCPCSUM) ^ 0xffff); |
| 858 | skb->ip_summed = CHECKSUM_HW; | 858 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 859 | skb->protocol = eth_type_trans(skb, gp->dev); | 859 | skb->protocol = eth_type_trans(skb, gp->dev); |
| 860 | 860 | ||
| 861 | netif_receive_skb(skb); | 861 | netif_receive_skb(skb); |
| @@ -1026,7 +1026,7 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev) · 164 unmodified lines | |||
| 1026 | unsigned long flags; | 1026 | unsigned long flags; |
| 1027 | 1027 | ||
| 1028 | ctrl = 0; | 1028 | ctrl = 0; |
| 1029 | if (skb->ip_summed == CHECKSUM_HW) { | 1029 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1030 | u64 csum_start_off, csum_stuff_off; | 1030 | u64 csum_start_off, csum_stuff_off; |
| 1031 | 1031 | ||
| 1032 | csum_start_off = (u64) (skb->h.raw - skb->data); | 1032 | csum_start_off = (u64) (skb->h.raw - skb->data); |
| @@ -1207,7 +1207,7 @@ static void happy_meal_transceiver_check(struct happy_meal *hp, void __iomem *tr · 1206 unmodified lines | |||
| 1207 | * flags, thus: | 1207 | * flags, thus: |
| 1208 | * | 1208 | * |
| 1209 | * skb->csum = rxd->rx_flags & 0xffff; | 1209 | * skb->csum = rxd->rx_flags & 0xffff; |
| 1210 | * skb->ip_summed = CHECKSUM_HW; | 1210 | * skb->ip_summed = CHECKSUM_COMPLETE; |
| 1211 | * | 1211 | * |
| 1212 | * before sending off the skb to the protocols, and we are good as gold. | 1212 | * before sending off the skb to the protocols, and we are good as gold. |
| 1213 | */ | 1213 | */ |
| @@ -2074,7 +2074,7 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev) · 860 unmodified lines | |||
| 2074 | 2074 | ||
| 2075 | /* This card is _fucking_ hot... */ | 2075 | /* This card is _fucking_ hot... */ |
| 2076 | skb->csum = ntohs(csum ^ 0xffff); | 2076 | skb->csum = ntohs(csum ^ 0xffff); |
| 2077 | skb->ip_summed = CHECKSUM_HW; | 2077 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 2078 | 2078 | ||
| 2079 | RXD(("len=%d csum=%4x]", len, csum)); | 2079 | RXD(("len=%d csum=%4x]", len, csum)); |
| 2080 | skb->protocol = eth_type_trans(skb, dev); | 2080 | skb->protocol = eth_type_trans(skb, dev); |
| @@ -2268,7 +2268,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) · 187 unmodified lines | |||
| 2268 | u32 tx_flags; | 2268 | u32 tx_flags; |
| 2269 | 2269 | ||
| 2270 | tx_flags = TXFLAG_OWN; | 2270 | tx_flags = TXFLAG_OWN; |
| 2271 | if (skb->ip_summed == CHECKSUM_HW) { | 2271 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 2272 | u32 csum_start_off, csum_stuff_off; | 2272 | u32 csum_start_off, csum_stuff_off; |
| 2273 | 2273 | ||
| 2274 | csum_start_off = (u32) (skb->h.raw - skb->data); | 2274 | csum_start_off = (u32) (skb->h.raw - skb->data); |
| @@ -149,122 +149,67 @@ module_param(tg3_debug, int, 0); · 148 unmodified lines | |||
| 149 | MODULE_PARM_DESC(tg3_debug, "Tigon3 bitmapped debugging message enable value"); | 149 | MODULE_PARM_DESC(tg3_debug, "Tigon3 bitmapped debugging message enable value"); |
| 150 | 150 | ||
| 151 | static struct pci_device_id tg3_pci_tbl[] = { | 151 | static struct pci_device_id tg3_pci_tbl[] = { |
| 152 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5700, | 152 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5700)}, |
| 153 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 153 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5701)}, |
| 154 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5701, | 154 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702)}, |
| 155 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 155 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703)}, |
| 156 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702, | 156 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704)}, |
| 157 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 157 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702FE)}, |
| 158 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703, | 158 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705)}, |
| 159 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 159 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705_2)}, |
| 160 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704, | 160 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705M)}, |
| 161 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 161 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705M_2)}, |
| 162 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702FE, | 162 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702X)}, |
| 163 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 163 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703X)}, |
| 164 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705, | 164 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S)}, |
| 165 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 165 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702A3)}, |
| 166 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705_2, | 166 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703A3)}, |
| 167 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 167 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5782)}, |
| 168 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705M, | 168 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5788)}, |
| 169 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 169 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5789)}, |
| 170 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705M_2, | 170 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901)}, |
| 171 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 171 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2)}, |
| 172 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702X, | 172 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S_2)}, |
| 173 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 173 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705F)}, |
| 174 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703X, | 174 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5720)}, |
| 175 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 175 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5721)}, |
| 176 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S, | 176 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750)}, |
| 177 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 177 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751)}, |
| 178 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702A3, | 178 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750M)}, |
| 179 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 179 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751M)}, |
| 180 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703A3, | 180 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751F)}, |
| 181 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 181 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752)}, |
| 182 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5782, | 182 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752M)}, |
| 183 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 183 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753)}, |
| 184 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5788, | 184 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753M)}, |
| 185 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 185 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753F)}, |
| 186 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5789, | 186 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754)}, |
| 187 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 187 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754M)}, |
| 188 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901, | 188 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755)}, |
| 189 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 189 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755M)}, |
| 190 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2, | 190 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5786)}, |
| 191 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 191 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787)}, |
| 192 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S_2, | 192 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M)}, |
| 193 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 193 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714)}, |
| 194 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705F, | 194 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714S)}, |
| 195 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 195 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715)}, |
| 196 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5720, | 196 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715S)}, |
| 197 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 197 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780)}, |
| 198 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5721, | 198 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S)}, |
| 199 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 199 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5781)}, |
| 200 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750, | 200 | {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)}, |
| 201 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 201 | {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)}, |
| 202 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751, | 202 | {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)}, |
| 203 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 203 | {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1001)}, |
| 204 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750M, | 204 | {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1003)}, |
| 205 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 205 | {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC9100)}, |
| 206 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751M, | 206 | {PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_TIGON3)}, |
| 207 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | 207 | {} |
| 208 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751F, | ||
| 209 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 210 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752, | ||
| 211 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 212 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752M, | ||
| 213 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 214 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753, | ||
| 215 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 216 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753M, | ||
| 217 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 218 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753F, | ||
| 219 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 220 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754, | ||
| 221 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 222 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754M, | ||
| 223 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 224 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755, | ||
| 225 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 226 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755M, | ||
| 227 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 228 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5786, | ||
| 229 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 230 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787, | ||
| 231 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 232 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M, | ||
| 233 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 234 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714, | ||
| 235 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 236 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714S, | ||
| 237 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 238 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715, | ||
| 239 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 240 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715S, | ||
| 241 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 242 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780, | ||
| 243 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 244 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S, | ||
| 245 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 246 | { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5781, | ||
| 247 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 248 | { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX, | ||
| 249 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 250 | { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX, | ||
| 251 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 252 | { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000, | ||
| 253 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 254 | { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1001, | ||
| 255 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 256 | { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1003, | ||
| 257 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 258 | { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC9100, | ||
| 259 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 260 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_TIGON3, | ||
| 261 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 262 | { 0, } | ||
| 263 | }; | 208 | }; |
| 264 | 209 | ||
| 265 | MODULE_DEVICE_TABLE(pci, tg3_pci_tbl); | 210 | MODULE_DEVICE_TABLE(pci, tg3_pci_tbl); |
| 266 | 211 | ||
| 267 | static struct { | 212 | static const struct { |
| 268 | const char string[ETH_GSTRING_LEN]; | 213 | const char string[ETH_GSTRING_LEN]; |
| 269 | } ethtool_stats_keys[TG3_NUM_STATS] = { | 214 | } ethtool_stats_keys[TG3_NUM_STATS] = { |
| 270 | { "rx_octets" }, | 215 | { "rx_octets" }, |
| @@ -345,7 +290,7 @@ static struct { · 74 unmodified lines | |||
| 345 | { "nic_tx_threshold_hit" } | 290 | { "nic_tx_threshold_hit" } |
| 346 | }; | 291 | }; |
| 347 | 292 | ||
| 348 | static struct { | 293 | static const struct { |
| 349 | const char string[ETH_GSTRING_LEN]; | 294 | const char string[ETH_GSTRING_LEN]; |
| 350 | } ethtool_test_keys[TG3_NUM_TEST] = { | 295 | } ethtool_test_keys[TG3_NUM_TEST] = { |
| 351 | { "nvram test (online) " }, | 296 | { "nvram test (online) " }, |
| @@ -3851,11 +3796,11 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) · 3499 unmodified lines | |||
| 3851 | skb->h.th->check = 0; | 3796 | skb->h.th->check = 0; |
| 3852 | 3797 | ||
| 3853 | } | 3798 | } |
| 3854 | else if (skb->ip_summed == CHECKSUM_HW) | 3799 | else if (skb->ip_summed == CHECKSUM_PARTIAL) |
| 3855 | base_flags |= TXD_FLAG_TCPUDP_CSUM; | 3800 | base_flags |= TXD_FLAG_TCPUDP_CSUM; |
| 3856 | #else | 3801 | #else |
| 3857 | mss = 0; | 3802 | mss = 0; |
| 3858 | if (skb->ip_summed == CHECKSUM_HW) | 3803 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
| 3859 | base_flags |= TXD_FLAG_TCPUDP_CSUM; | 3804 | base_flags |= TXD_FLAG_TCPUDP_CSUM; |
| 3860 | #endif | 3805 | #endif |
| 3861 | #if TG3_VLAN_TAG_USED | 3806 | #if TG3_VLAN_TAG_USED |
| @@ -3981,7 +3926,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) · 119 unmodified lines | |||
| 3981 | 3926 | ||
| 3982 | entry = tp->tx_prod; | 3927 | entry = tp->tx_prod; |
| 3983 | base_flags = 0; | 3928 | base_flags = 0; |
| 3984 | if (skb->ip_summed == CHECKSUM_HW) | 3929 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
| 3985 | base_flags |= TXD_FLAG_TCPUDP_CSUM; | 3930 | base_flags |= TXD_FLAG_TCPUDP_CSUM; |
| 3986 | #if TG3_TSO_SUPPORT != 0 | 3931 | #if TG3_TSO_SUPPORT != 0 |
| 3987 | mss = 0; | 3932 | mss = 0; |
| @@ -4969,7 +4914,7 @@ static int tg3_halt(struct tg3 *tp, int kind, int silent) · 981 unmodified lines | |||
| 4969 | #define TG3_FW_BSS_ADDR 0x08000a70 | 4914 | #define TG3_FW_BSS_ADDR 0x08000a70 |
| 4970 | #define TG3_FW_BSS_LEN 0x10 | 4915 | #define TG3_FW_BSS_LEN 0x10 |
| 4971 | 4916 | ||
| 4972 | static u32 tg3FwText[(TG3_FW_TEXT_LEN / sizeof(u32)) + 1] = { | 4917 | static const u32 tg3FwText[(TG3_FW_TEXT_LEN / sizeof(u32)) + 1] = { |
| 4973 | 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c1d0800, | 4918 | 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c1d0800, |
| 4974 | 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100000, 0x0e000018, 0x00000000, | 4919 | 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100000, 0x0e000018, 0x00000000, |
| 4975 | 0x0000000d, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100034, | 4920 | 0x0000000d, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100034, |
| @@ -5063,7 +5008,7 @@ static u32 tg3FwText[(TG3_FW_TEXT_LEN / sizeof(u32)) + 1] = { · 87 unmodified lines | |||
| 5063 | 0x27bd0008, 0x03e00008, 0x00000000, 0x00000000, 0x00000000 | 5008 | 0x27bd0008, 0x03e00008, 0x00000000, 0x00000000, 0x00000000 |
| 5064 | }; | 5009 | }; |
| 5065 | 5010 | ||
| 5066 | static u32 tg3FwRodata[(TG3_FW_RODATA_LEN / sizeof(u32)) + 1] = { | 5011 | static const u32 tg3FwRodata[(TG3_FW_RODATA_LEN / sizeof(u32)) + 1] = { |
| 5067 | 0x35373031, 0x726c7341, 0x00000000, 0x00000000, 0x53774576, 0x656e7430, | 5012 | 0x35373031, 0x726c7341, 0x00000000, 0x00000000, 0x53774576, 0x656e7430, |
| 5068 | 0x00000000, 0x726c7045, 0x76656e74, 0x31000000, 0x556e6b6e, 0x45766e74, | 5013 | 0x00000000, 0x726c7045, 0x76656e74, 0x31000000, 0x556e6b6e, 0x45766e74, |
| 5069 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x66617461, 0x6c457272, | 5014 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x66617461, 0x6c457272, |
| @@ -5128,13 +5073,13 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset) · 58 unmodified lines | |||
| 5128 | struct fw_info { | 5073 | struct fw_info { |
| 5129 | unsigned int text_base; | 5074 | unsigned int text_base; |
| 5130 | unsigned int text_len; | 5075 | unsigned int text_len; |
| 5131 | u32 *text_data; | 5076 | const u32 *text_data; |
| 5132 | unsigned int rodata_base; | 5077 | unsigned int rodata_base; |
| 5133 | unsigned int rodata_len; | 5078 | unsigned int rodata_len; |
| 5134 | u32 *rodata_data; | 5079 | const u32 *rodata_data; |
| 5135 | unsigned int data_base; | 5080 | unsigned int data_base; |
| 5136 | unsigned int data_len; | 5081 | unsigned int data_len; |
| 5137 | u32 *data_data; | 5082 | const u32 *data_data; |
| 5138 | }; | 5083 | }; |
| 5139 | 5084 | ||
| 5140 | /* tp->lock is held. */ | 5085 | /* tp->lock is held. */ |
| @@ -5266,7 +5211,7 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) · 125 unmodified lines | |||
| 5266 | #define TG3_TSO_FW_BSS_ADDR 0x08001b80 | 5211 | #define TG3_TSO_FW_BSS_ADDR 0x08001b80 |
| 5267 | #define TG3_TSO_FW_BSS_LEN 0x894 | 5212 | #define TG3_TSO_FW_BSS_LEN 0x894 |
| 5268 | 5213 | ||
| 5269 | static u32 tg3TsoFwText[(TG3_TSO_FW_TEXT_LEN / 4) + 1] = { | 5214 | static const u32 tg3TsoFwText[(TG3_TSO_FW_TEXT_LEN / 4) + 1] = { |
| 5270 | 0x0e000003, 0x00000000, 0x08001b24, 0x00000000, 0x10000003, 0x00000000, | 5215 | 0x0e000003, 0x00000000, 0x08001b24, 0x00000000, 0x10000003, 0x00000000, |
| 5271 | 0x0000000d, 0x0000000d, 0x3c1d0800, 0x37bd4000, 0x03a0f021, 0x3c100800, | 5216 | 0x0000000d, 0x0000000d, 0x3c1d0800, 0x37bd4000, 0x03a0f021, 0x3c100800, |
| 5272 | 0x26100000, 0x0e000010, 0x00000000, 0x0000000d, 0x27bdffe0, 0x3c04fefe, | 5217 | 0x26100000, 0x0e000010, 0x00000000, 0x0000000d, 0x27bdffe0, 0x3c04fefe, |
| @@ -5553,7 +5498,7 @@ static u32 tg3TsoFwText[(TG3_TSO_FW_TEXT_LEN / 4) + 1] = { · 280 unmodified lines | |||
| 5553 | 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, 0x00000000, 0x00000000, | 5498 | 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, 0x00000000, 0x00000000, |
| 5554 | }; | 5499 | }; |
| 5555 | 5500 | ||
| 5556 | static u32 tg3TsoFwRodata[] = { | 5501 | static const u32 tg3TsoFwRodata[] = { |
| 5557 | 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, | 5502 | 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, |
| 5558 | 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x496e0000, 0x73746b6f, | 5503 | 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x496e0000, 0x73746b6f, |
| 5559 | 0x66662a2a, 0x00000000, 0x53774576, 0x656e7430, 0x00000000, 0x00000000, | 5504 | 0x66662a2a, 0x00000000, 0x53774576, 0x656e7430, 0x00000000, 0x00000000, |
| @@ -5561,7 +5506,7 @@ static u32 tg3TsoFwRodata[] = { · 1 unmodified line | |||
| 5561 | 0x00000000, | 5506 | 0x00000000, |
| 5562 | }; | 5507 | }; |
| 5563 | 5508 | ||
| 5564 | static u32 tg3TsoFwData[] = { | 5509 | static const u32 tg3TsoFwData[] = { |
| 5565 | 0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, 0x362e3000, 0x00000000, | 5510 | 0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, 0x362e3000, 0x00000000, |
| 5566 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 5511 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 5567 | 0x00000000, | 5512 | 0x00000000, |
| @@ -5583,7 +5528,7 @@ static u32 tg3TsoFwData[] = { · 15 unmodified lines | |||
| 5583 | #define TG3_TSO5_FW_BSS_ADDR 0x00010f50 | 5528 | #define TG3_TSO5_FW_BSS_ADDR 0x00010f50 |
| 5584 | #define TG3_TSO5_FW_BSS_LEN 0x88 | 5529 | #define TG3_TSO5_FW_BSS_LEN 0x88 |
| 5585 | 5530 | ||
| 5586 | static u32 tg3Tso5FwText[(TG3_TSO5_FW_TEXT_LEN / 4) + 1] = { | 5531 | static const u32 tg3Tso5FwText[(TG3_TSO5_FW_TEXT_LEN / 4) + 1] = { |
| 5587 | 0x0c004003, 0x00000000, 0x00010f04, 0x00000000, 0x10000003, 0x00000000, | 5532 | 0x0c004003, 0x00000000, 0x00010f04, 0x00000000, 0x10000003, 0x00000000, |
| 5588 | 0x0000000d, 0x0000000d, 0x3c1d0001, 0x37bde000, 0x03a0f021, 0x3c100001, | 5533 | 0x0000000d, 0x0000000d, 0x3c1d0001, 0x37bde000, 0x03a0f021, 0x3c100001, |
| 5589 | 0x26100000, 0x0c004010, 0x00000000, 0x0000000d, 0x27bdffe0, 0x3c04fefe, | 5534 | 0x26100000, 0x0c004010, 0x00000000, 0x0000000d, 0x27bdffe0, 0x3c04fefe, |
| @@ -5742,14 +5687,14 @@ static u32 tg3Tso5FwText[(TG3_TSO5_FW_TEXT_LEN / 4) + 1] = { · 152 unmodified lines | |||
| 5742 | 0x00000000, 0x00000000, 0x00000000, | 5687 | 0x00000000, 0x00000000, 0x00000000, |
| 5743 | }; | 5688 | }; |
| 5744 | 5689 | ||
| 5745 | static u32 tg3Tso5FwRodata[(TG3_TSO5_FW_RODATA_LEN / 4) + 1] = { | 5690 | static const u32 tg3Tso5FwRodata[(TG3_TSO5_FW_RODATA_LEN / 4) + 1] = { |
| 5746 | 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, | 5691 | 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, |
| 5747 | 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, | 5692 | 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, |
| 5748 | 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, 0x66617461, 0x6c457272, | 5693 | 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, 0x66617461, 0x6c457272, |
| 5749 | 0x00000000, 0x00000000, 0x00000000, | 5694 | 0x00000000, 0x00000000, 0x00000000, |
| 5750 | }; | 5695 | }; |
| 5751 | 5696 | ||
| 5752 | static u32 tg3Tso5FwData[(TG3_TSO5_FW_DATA_LEN / 4) + 1] = { | 5697 | static const u32 tg3Tso5FwData[(TG3_TSO5_FW_DATA_LEN / 4) + 1] = { |
| 5753 | 0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, 0x322e3000, 0x00000000, | 5698 | 0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, 0x322e3000, 0x00000000, |
| 5754 | 0x00000000, 0x00000000, 0x00000000, | 5699 | 0x00000000, 0x00000000, 0x00000000, |
| 5755 | }; | 5700 | }; |
| @@ -830,7 +830,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) · 829 unmodified lines | |||
| 830 | first_txd->addrHi = (u64)((unsigned long) skb) >> 32; | 830 | first_txd->addrHi = (u64)((unsigned long) skb) >> 32; |
| 831 | first_txd->processFlags = 0; | 831 | first_txd->processFlags = 0; |
| 832 | 832 | ||
| 833 | if(skb->ip_summed == CHECKSUM_HW) { | 833 | if(skb->ip_summed == CHECKSUM_PARTIAL) { |
| 834 | /* The 3XP will figure out if this is UDP/TCP */ | 834 | /* The 3XP will figure out if this is UDP/TCP */ |
| 835 | first_txd->processFlags |= TYPHOON_TX_PF_TCP_CHKSUM; | 835 | first_txd->processFlags |= TYPHOON_TX_PF_TCP_CHKSUM; |
| 836 | first_txd->processFlags |= TYPHOON_TX_PF_UDP_CHKSUM; | 836 | first_txd->processFlags |= TYPHOON_TX_PF_UDP_CHKSUM; |
| @@ -1230,7 +1230,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev) · 1229 unmodified lines | |||
| 1230 | rp->tx_skbuff[entry] = skb; | 1230 | rp->tx_skbuff[entry] = skb; |
| 1231 | 1231 | ||
| 1232 | if ((rp->quirks & rqRhineI) && | 1232 | if ((rp->quirks & rqRhineI) && |
| 1233 | (((unsigned long)skb->data & 3) || skb_shinfo(skb)->nr_frags != 0 || skb->ip_summed == CHECKSUM_HW)) { | 1233 | (((unsigned long)skb->data & 3) || skb_shinfo(skb)->nr_frags != 0 || skb->ip_summed == CHECKSUM_PARTIAL)) { |
| 1234 | /* Must use alignment buffer. */ | 1234 | /* Must use alignment buffer. */ |
| 1235 | if (skb->len > PKT_BUF_SZ) { | 1235 | if (skb->len > PKT_BUF_SZ) { |
| 1236 | /* packet too long, drop it */ | 1236 | /* packet too long, drop it */ |
| @@ -2002,7 +2002,7 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) · 2001 unmodified lines | |||
| 2002 | * Handle hardware checksum | 2002 | * Handle hardware checksum |
| 2003 | */ | 2003 | */ |
| 2004 | if ((vptr->flags & VELOCITY_FLAGS_TX_CSUM) | 2004 | if ((vptr->flags & VELOCITY_FLAGS_TX_CSUM) |
| 2005 | && (skb->ip_summed == CHECKSUM_HW)) { | 2005 | && (skb->ip_summed == CHECKSUM_PARTIAL)) { |
| 2006 | struct iphdr *ip = skb->nh.iph; | 2006 | struct iphdr *ip = skb->nh.iph; |
| 2007 | if (ip->protocol == IPPROTO_TCP) | 2007 | if (ip->protocol == IPPROTO_TCP) |
| 2008 | td_ptr->tdesc1.TCR |= TCR0_TCPCK; | 2008 | td_ptr->tdesc1.TCR |= TCR0_TCPCK; |
| @@ -1826,8 +1826,8 @@ static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd) · 1825 unmodified lines | |||
| 1826 | { | 1826 | { |
| 1827 | struct riva_par *par = info->par; | 1827 | struct riva_par *par = info->par; |
| 1828 | struct device_node *dp; | 1828 | struct device_node *dp; |
| 1829 | unsigned char *pedid = NULL; | 1829 | const unsigned char *pedid = NULL; |
| 1830 | unsigned char *disptype = NULL; | 1830 | const unsigned char *disptype = NULL; |
| 1831 | static char *propnames[] = { | 1831 | static char *propnames[] = { |
| 1832 | "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL }; | 1832 | "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL }; |
| 1833 | int i; | 1833 | int i; |
| @@ -1471,8 +1471,8 @@ config NFS_V4 · 1470 unmodified lines | |||
| 1471 | If unsure, say N. | 1471 | If unsure, say N. |
| 1472 | 1472 | ||
| 1473 | config NFS_DIRECTIO | 1473 | config NFS_DIRECTIO |
| 1474 | bool "Allow direct I/O on NFS files (EXPERIMENTAL)" | 1474 | bool "Allow direct I/O on NFS files" |
| 1475 | depends on NFS_FS && EXPERIMENTAL | 1475 | depends on NFS_FS |
| 1476 | help | 1476 | help |
| 1477 | This option enables applications to perform uncached I/O on files | 1477 | This option enables applications to perform uncached I/O on files |
| 1478 | in NFS file systems using the O_DIRECT open() flag. When O_DIRECT | 1478 | in NFS file systems using the O_DIRECT open() flag. When O_DIRECT |
| @@ -828,17 +828,19 @@ void d_instantiate(struct dentry *entry, struct inode * inode) · 827 unmodified lines | |||
| 828 | * (or otherwise set) by the caller to indicate that it is now | 828 | * (or otherwise set) by the caller to indicate that it is now |
| 829 | * in use by the dcache. | 829 | * in use by the dcache. |
| 830 | */ | 830 | */ |
| 831 | struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode) | 831 | static struct dentry *__d_instantiate_unique(struct dentry *entry, |
| 832 | struct inode *inode) | ||
| 832 | { | 833 | { |
| 833 | struct dentry *alias; | 834 | struct dentry *alias; |
| 834 | int len = entry->d_name.len; | 835 | int len = entry->d_name.len; |
| 835 | const char *name = entry->d_name.name; | 836 | const char *name = entry->d_name.name; |
| 836 | unsigned int hash = entry->d_name.hash; | 837 | unsigned int hash = entry->d_name.hash; |
| 837 | 838 | ||
| 838 | BUG_ON(!list_empty(&entry->d_alias)); | 839 | if (!inode) { |
| 839 | spin_lock(&dcache_lock); | 840 | entry->d_inode = NULL; |
| 840 | if (!inode) | 841 | return NULL; |
| 841 | goto do_negative; | 842 | } |
| 843 | |||
| 842 | list_for_each_entry(alias, &inode->i_dentry, d_alias) { | 844 | list_for_each_entry(alias, &inode->i_dentry, d_alias) { |
| 843 | struct qstr *qstr = &alias->d_name; | 845 | struct qstr *qstr = &alias->d_name; |
| 844 | 846 | ||
| @@ -851,19 +853,35 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode) · 6 unmodified lines | |||
| 851 | if (memcmp(qstr->name, name, len)) | 853 | if (memcmp(qstr->name, name, len)) |
| 852 | continue; | 854 | continue; |
| 853 | dget_locked(alias); | 855 | dget_locked(alias); |
| 854 | spin_unlock(&dcache_lock); | ||
| 855 | BUG_ON(!d_unhashed(alias)); | ||
| 856 | iput(inode); | ||
| 857 | return alias; | 856 | return alias; |
| 858 | } | 857 | } |
| 858 | |||
| 859 | list_add(&entry->d_alias, &inode->i_dentry); | 859 | list_add(&entry->d_alias, &inode->i_dentry); |
| 860 | do_negative: | ||
| 861 | entry->d_inode = inode; | 860 | entry->d_inode = inode; |
| 862 | fsnotify_d_instantiate(entry, inode); | 861 | fsnotify_d_instantiate(entry, inode); |
| 863 | spin_unlock(&dcache_lock); | ||
| 864 | security_d_instantiate(entry, inode); | ||
| 865 | return NULL; | 862 | return NULL; |
| 866 | } | 863 | } |
| 864 | |||
| 865 | struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode) | ||
| 866 | { | ||
| 867 | struct dentry *result; | ||
| 868 | |||
| 869 | BUG_ON(!list_empty(&entry->d_alias)); | ||
| 870 | |||
| 871 | spin_lock(&dcache_lock); | ||
| 872 | result = __d_instantiate_unique(entry, inode); | ||
| 873 | spin_unlock(&dcache_lock); | ||
| 874 | |||
| 875 | if (!result) { | ||
| 876 | security_d_instantiate(entry, inode); | ||
| 877 | return NULL; | ||
| 878 | } | ||
| 879 | |||
| 880 | BUG_ON(!d_unhashed(result)); | ||
| 881 | iput(inode); | ||
| 882 | return result; | ||
| 883 | } | ||
| 884 | |||
| 867 | EXPORT_SYMBOL(d_instantiate_unique); | 885 | EXPORT_SYMBOL(d_instantiate_unique); |
| 868 | 886 | ||
| 869 | /** | 887 | /** |
| @@ -1235,6 +1253,11 @@ static void __d_rehash(struct dentry * entry, struct hlist_head *list) · 365 unmodified lines | |||
| 1235 | hlist_add_head_rcu(&entry->d_hash, list); | 1253 | hlist_add_head_rcu(&entry->d_hash, list); |
| 1236 | } | 1254 | } |
| 1237 | 1255 | ||
| 1256 | static void _d_rehash(struct dentry * entry) | ||
| 1257 | { | ||
| 1258 | __d_rehash(entry, d_hash(entry->d_parent, entry->d_name.hash)); | ||
| 1259 | } | ||
| 1260 | |||
| 1238 | /** | 1261 | /** |
| 1239 | * d_rehash - add an entry back to the hash | 1262 | * d_rehash - add an entry back to the hash |
| 1240 | * @entry: dentry to add to the hash | 1263 | * @entry: dentry to add to the hash |
| @@ -1244,11 +1267,9 @@ static void __d_rehash(struct dentry * entry, struct hlist_head *list) · 3 unmodified lines | |||
| 1244 | 1267 | ||
| 1245 | void d_rehash(struct dentry * entry) | 1268 | void d_rehash(struct dentry * entry) |
| 1246 | { | 1269 | { |
| 1247 | struct hlist_head *list = d_hash(entry->d_parent, entry->d_name.hash); | ||
| 1248 | |||
| 1249 | spin_lock(&dcache_lock); | 1270 | spin_lock(&dcache_lock); |
| 1250 | spin_lock(&entry->d_lock); | 1271 | spin_lock(&entry->d_lock); |
| 1251 | __d_rehash(entry, list); | 1272 | _d_rehash(entry); |
| 1252 | spin_unlock(&entry->d_lock); | 1273 | spin_unlock(&entry->d_lock); |
| 1253 | spin_unlock(&dcache_lock); | 1274 | spin_unlock(&dcache_lock); |
| 1254 | } | 1275 | } |
| @@ -1386,6 +1407,120 @@ already_unhashed: · 131 unmodified lines | |||
| 1386 | spin_unlock(&dcache_lock); | 1407 | spin_unlock(&dcache_lock); |
| 1387 | } | 1408 | } |
| 1388 | 1409 | ||
| 1410 | /* | ||
| 1411 | * Prepare an anonymous dentry for life in the superblock's dentry tree as a | ||
| 1412 | * named dentry in place of the dentry to be replaced. | ||
| 1413 | */ | ||
| 1414 | static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon) | ||
| 1415 | { | ||
| 1416 | struct dentry *dparent, *aparent; | ||
| 1417 | |||
| 1418 | switch_names(dentry, anon); | ||
| 1419 | do_switch(dentry->d_name.len, anon->d_name.len); | ||
| 1420 | do_switch(dentry->d_name.hash, anon->d_name.hash); | ||
| 1421 | |||
| 1422 | dparent = dentry->d_parent; | ||
| 1423 | aparent = anon->d_parent; | ||
| 1424 | |||
| 1425 | dentry->d_parent = (aparent == anon) ? dentry : aparent; | ||
| 1426 | list_del(&dentry->d_u.d_child); | ||
| 1427 | if (!IS_ROOT(dentry)) | ||
| 1428 | list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs); | ||
| 1429 | else | ||
| 1430 | INIT_LIST_HEAD(&dentry->d_u.d_child); | ||
| 1431 | |||
| 1432 | anon->d_parent = (dparent == dentry) ? anon : dparent; | ||
| 1433 | list_del(&anon->d_u.d_child); | ||
| 1434 | if (!IS_ROOT(anon)) | ||
| 1435 | list_add(&anon->d_u.d_child, &anon->d_parent->d_subdirs); | ||
| 1436 | else | ||
| 1437 | INIT_LIST_HEAD(&anon->d_u.d_child); | ||
| 1438 | |||
| 1439 | anon->d_flags &= ~DCACHE_DISCONNECTED; | ||
| 1440 | } | ||
| 1441 | |||
| 1442 | /** | ||
| 1443 | * d_materialise_unique - introduce an inode into the tree | ||
| 1444 | * @dentry: candidate dentry | ||
| 1445 | * @inode: inode to bind to the dentry, to which aliases may be attached | ||
| 1446 | * | ||
| 1447 | * Introduces an dentry into the tree, substituting an extant disconnected | ||
| 1448 | * root directory alias in its place if there is one | ||
| 1449 | */ | ||
| 1450 | struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) | ||
| 1451 | { | ||
| 1452 | struct dentry *alias, *actual; | ||
| 1453 | |||
| 1454 | BUG_ON(!d_unhashed(dentry)); | ||
| 1455 | |||
| 1456 | spin_lock(&dcache_lock); | ||
| 1457 | |||
| 1458 | if (!inode) { | ||
| 1459 | actual = dentry; | ||
| 1460 | dentry->d_inode = NULL; | ||
| 1461 | goto found_lock; | ||
| 1462 | } | ||
| 1463 | |||
| 1464 | /* See if a disconnected directory already exists as an anonymous root | ||
| 1465 | * that we should splice into the tree instead */ | ||
| 1466 | if (S_ISDIR(inode->i_mode) && (alias = __d_find_alias(inode, 1))) { | ||
| 1467 | spin_lock(&alias->d_lock); | ||
| 1468 | |||
| 1469 | /* Is this a mountpoint that we could splice into our tree? */ | ||
| 1470 | if (IS_ROOT(alias)) | ||
| 1471 | goto connect_mountpoint; | ||
| 1472 | |||
| 1473 | if (alias->d_name.len == dentry->d_name.len && | ||
| 1474 | alias->d_parent == dentry->d_parent && | ||
| 1475 | memcmp(alias->d_name.name, | ||
| 1476 | dentry->d_name.name, | ||
| 1477 | dentry->d_name.len) == 0) | ||
| 1478 | goto replace_with_alias; | ||
| 1479 | |||
| 1480 | spin_unlock(&alias->d_lock); | ||
| 1481 | |||
| 1482 | /* Doh! Seem to be aliasing directories for some reason... */ | ||
| 1483 | dput(alias); | ||
| 1484 | } | ||
| 1485 | |||
| 1486 | /* Add a unique reference */ | ||
| 1487 | actual = __d_instantiate_unique(dentry, inode); | ||
| 1488 | if (!actual) | ||
| 1489 | actual = dentry; | ||
| 1490 | else if (unlikely(!d_unhashed(actual))) | ||
| 1491 | goto shouldnt_be_hashed; | ||
| 1492 | |||
| 1493 | found_lock: | ||
| 1494 | spin_lock(&actual->d_lock); | ||
| 1495 | found: | ||
| 1496 | _d_rehash(actual); | ||
| 1497 | spin_unlock(&actual->d_lock); | ||
| 1498 | spin_unlock(&dcache_lock); | ||
| 1499 | |||
| 1500 | if (actual == dentry) { | ||
| 1501 | security_d_instantiate(dentry, inode); | ||
| 1502 | return NULL; | ||
| 1503 | } | ||
| 1504 | |||
| 1505 | iput(inode); | ||
| 1506 | return actual; | ||
| 1507 | |||
| 1508 | /* Convert the anonymous/root alias into an ordinary dentry */ | ||
| 1509 | connect_mountpoint: | ||
| 1510 | __d_materialise_dentry(dentry, alias); | ||
| 1511 | |||
| 1512 | /* Replace the candidate dentry with the alias in the tree */ | ||
| 1513 | replace_with_alias: | ||
| 1514 | __d_drop(alias); | ||
| 1515 | actual = alias; | ||
| 1516 | goto found; | ||
| 1517 | |||
| 1518 | shouldnt_be_hashed: | ||
| 1519 | spin_unlock(&dcache_lock); | ||
| 1520 | BUG(); | ||
| 1521 | goto shouldnt_be_hashed; | ||
| 1522 | } | ||
| 1523 | |||
| 1389 | /** | 1524 | /** |
| 1390 | * d_path - return the path of a dentry | 1525 | * d_path - return the path of a dentry |
| 1391 | * @dentry: dentry to report | 1526 | * @dentry: dentry to report |
| @@ -1784,6 +1919,7 @@ EXPORT_SYMBOL(d_instantiate); · 392 unmodified lines | |||
| 1784 | EXPORT_SYMBOL(d_invalidate); | 1919 | EXPORT_SYMBOL(d_invalidate); |
| 1785 | EXPORT_SYMBOL(d_lookup); | 1920 | EXPORT_SYMBOL(d_lookup); |
| 1786 | EXPORT_SYMBOL(d_move); | 1921 | EXPORT_SYMBOL(d_move); |
| 1922 | EXPORT_SYMBOL_GPL(d_materialise_unique); | ||
| 1787 | EXPORT_SYMBOL(d_path); | 1923 | EXPORT_SYMBOL(d_path); |
| 1788 | EXPORT_SYMBOL(d_prune_aliases); | 1924 | EXPORT_SYMBOL(d_prune_aliases); |
| 1789 | EXPORT_SYMBOL(d_rehash); | 1925 | EXPORT_SYMBOL(d_rehash); |
| @@ -151,11 +151,13 @@ static void nlmclnt_release_lockargs(struct nlm_rqst *req) · 150 unmodified lines | |||
| 151 | int | 151 | int |
| 152 | nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl) | 152 | nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl) |
| 153 | { | 153 | { |
| 154 | struct rpc_clnt *client = NFS_CLIENT(inode); | ||
| 155 | struct sockaddr_in addr; | ||
| 154 | struct nlm_host *host; | 156 | struct nlm_host *host; |
| 155 | struct nlm_rqst *call; | 157 | struct nlm_rqst *call; |
| 156 | sigset_t oldset; | 158 | sigset_t oldset; |
| 157 | unsigned long flags; | 159 | unsigned long flags; |
| 158 | int status, proto, vers; | 160 | int status, vers; |
| 159 | 161 | ||
| 160 | vers = (NFS_PROTO(inode)->version == 3) ? 4 : 1; | 162 | vers = (NFS_PROTO(inode)->version == 3) ? 4 : 1; |
| 161 | if (NFS_PROTO(inode)->version > 3) { | 163 | if (NFS_PROTO(inode)->version > 3) { |
| @@ -163,10 +165,8 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl) · 1 unmodified line | |||
| 163 | return -ENOLCK; | 165 | return -ENOLCK; |
| 164 | } | 166 | } |
| 165 | 167 | ||
| 166 | /* Retrieve transport protocol from NFS client */ | 168 | rpc_peeraddr(client, (struct sockaddr *) &addr, sizeof(addr)); |
| 167 | proto = NFS_CLIENT(inode)->cl_xprt->prot; | 169 | host = nlmclnt_lookup_host(&addr, client->cl_xprt->prot, vers); |
| 168 | |||
| 169 | host = nlmclnt_lookup_host(NFS_ADDR(inode), proto, vers); | ||
| 170 | if (host == NULL) | 170 | if (host == NULL) |
| 171 | return -ENOLCK; | 171 | return -ENOLCK; |
| 172 | 172 | ||
| @@ -26,7 +26,6 @@ · 25 unmodified lines | |||
| 26 | #define NLM_HOST_REBIND (60 * HZ) | 26 | #define NLM_HOST_REBIND (60 * HZ) |
| 27 | #define NLM_HOST_EXPIRE ((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ) | 27 | #define NLM_HOST_EXPIRE ((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ) |
| 28 | #define NLM_HOST_COLLECT ((nrhosts > NLM_HOST_MAX)? 120 * HZ : 60 * HZ) | 28 | #define NLM_HOST_COLLECT ((nrhosts > NLM_HOST_MAX)? 120 * HZ : 60 * HZ) |
| 29 | #define NLM_HOST_ADDR(sv) (&(sv)->s_nlmclnt->cl_xprt->addr) | ||
| 30 | 29 | ||
| 31 | static struct nlm_host * nlm_hosts[NLM_HOST_NRHASH]; | 30 | static struct nlm_host * nlm_hosts[NLM_HOST_NRHASH]; |
| 32 | static unsigned long next_gc; | 31 | static unsigned long next_gc; |
| @@ -167,7 +166,6 @@ struct rpc_clnt * · 134 unmodified lines | |||
| 167 | nlm_bind_host(struct nlm_host *host) | 166 | nlm_bind_host(struct nlm_host *host) |
| 168 | { | 167 | { |
| 169 | struct rpc_clnt *clnt; | 168 | struct rpc_clnt *clnt; |
| 170 | struct rpc_xprt *xprt; | ||
| 171 | 169 | ||
| 172 | dprintk("lockd: nlm_bind_host(%08x)\n", | 170 | dprintk("lockd: nlm_bind_host(%08x)\n", |
| 173 | (unsigned)ntohl(host->h_addr.sin_addr.s_addr)); | 171 | (unsigned)ntohl(host->h_addr.sin_addr.s_addr)); |
| @@ -179,7 +177,6 @@ nlm_bind_host(struct nlm_host *host) · 5 unmodified lines | |||
| 179 | * RPC rebind is required | 177 | * RPC rebind is required |
| 180 | */ | 178 | */ |
| 181 | if ((clnt = host->h_rpcclnt) != NULL) { | 179 | if ((clnt = host->h_rpcclnt) != NULL) { |
| 182 | xprt = clnt->cl_xprt; | ||
| 183 | if (time_after_eq(jiffies, host->h_nextrebind)) { | 180 | if (time_after_eq(jiffies, host->h_nextrebind)) { |
| 184 | rpc_force_rebind(clnt); | 181 | rpc_force_rebind(clnt); |
| 185 | host->h_nextrebind = jiffies + NLM_HOST_REBIND; | 182 | host->h_nextrebind = jiffies + NLM_HOST_REBIND; |
| @@ -187,31 +184,37 @@ nlm_bind_host(struct nlm_host *host) · 1 unmodified line | |||
| 187 | host->h_nextrebind - jiffies); | 184 | host->h_nextrebind - jiffies); |
| 188 | } | 185 | } |
| 189 | } else { | 186 | } else { |
| 190 | xprt = xprt_create_proto(host->h_proto, &host->h_addr, NULL); | 187 | unsigned long increment = nlmsvc_timeout * HZ; |
| 191 | if (IS_ERR(xprt)) | 188 | struct rpc_timeout timeparms = { |
| 192 | goto forgetit; | 189 | .to_initval = increment, |
| 193 | 190 | .to_increment = increment, | |
| 194 | xprt_set_timeout(&xprt->timeout, 5, nlmsvc_timeout); | 191 | .to_maxval = increment * 6UL, |
| 195 | xprt->resvport = 1; /* NLM requires a reserved port */ | 192 | .to_retries = 5U, |
| 196 | 193 | }; | |
| 197 | /* Existing NLM servers accept AUTH_UNIX only */ | 194 | struct rpc_create_args args = { |
| 198 | clnt = rpc_new_client(xprt, host->h_name, &nlm_program, | 195 | .protocol = host->h_proto, |
| 199 | host->h_version, RPC_AUTH_UNIX); | 196 | .address = (struct sockaddr *)&host->h_addr, |
| 200 | if (IS_ERR(clnt)) | 197 | .addrsize = sizeof(host->h_addr), |
| 201 | goto forgetit; | 198 | .timeout = &timeparms, |
| 202 | clnt->cl_autobind = 1; /* turn on pmap queries */ | 199 | .servername = host->h_name, |
| 203 | clnt->cl_softrtry = 1; /* All queries are soft */ | 200 | .program = &nlm_program, |
| 204 | 201 | .version = host->h_version, | |
| 205 | host->h_rpcclnt = clnt; | 202 | .authflavor = RPC_AUTH_UNIX, |
| 203 | .flags = (RPC_CLNT_CREATE_HARDRTRY | | ||
| 204 | RPC_CLNT_CREATE_AUTOBIND), | ||
| 205 | }; | ||
| 206 | |||
| 207 | clnt = rpc_create(&args); | ||
| 208 | if (!IS_ERR(clnt)) | ||
| 209 | host->h_rpcclnt = clnt; | ||
| 210 | else { | ||
| 211 | printk("lockd: couldn't create RPC handle for %s\n", host->h_name); | ||
| 212 | clnt = NULL; | ||
| 213 | } | ||
| 206 | } | 214 | } |
| 207 | 215 | ||
| 208 | mutex_unlock(&host->h_mutex); | 216 | mutex_unlock(&host->h_mutex); |
| 209 | return clnt; | 217 | return clnt; |
| 210 | |||
| 211 | forgetit: | ||
| 212 | printk("lockd: couldn't create RPC handle for %s\n", host->h_name); | ||
| 213 | mutex_unlock(&host->h_mutex); | ||
| 214 | return NULL; | ||
| 215 | } | 218 | } |
| 216 | 219 | ||
| 217 | /* | 220 | /* |
| @@ -109,30 +109,23 @@ nsm_unmonitor(struct nlm_host *host) · 108 unmodified lines | |||
| 109 | static struct rpc_clnt * | 109 | static struct rpc_clnt * |
| 110 | nsm_create(void) | 110 | nsm_create(void) |
| 111 | { | 111 | { |
| 112 | struct rpc_xprt *xprt; | 112 | struct sockaddr_in sin = { |
| 113 | struct rpc_clnt *clnt; | 113 | .sin_family = AF_INET, |
| 114 | struct sockaddr_in sin; | 114 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), |
| 115 | 115 | .sin_port = 0, | |
| 116 | sin.sin_family = AF_INET; | 116 | }; |
| 117 | sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); | 117 | struct rpc_create_args args = { |
| 118 | sin.sin_port = 0; | 118 | .protocol = IPPROTO_UDP, |
| 119 | 119 | .address = (struct sockaddr *)&sin, | |
| 120 | xprt = xprt_create_proto(IPPROTO_UDP, &sin, NULL); | 120 | .addrsize = sizeof(sin), |
| 121 | if (IS_ERR(xprt)) | 121 | .servername = "localhost", |
| 122 | return (struct rpc_clnt *)xprt; | 122 | .program = &nsm_program, |
| 123 | xprt->resvport = 1; /* NSM requires a reserved port */ | 123 | .version = SM_VERSION, |
| 124 | 124 | .authflavor = RPC_AUTH_NULL, | |
| 125 | clnt = rpc_create_client(xprt, "localhost", | 125 | .flags = (RPC_CLNT_CREATE_ONESHOT), |
| 126 | &nsm_program, SM_VERSION, | 126 | }; |
| 127 | RPC_AUTH_NULL); | 127 | |
| 128 | if (IS_ERR(clnt)) | 128 | return rpc_create(&args); |
| 129 | goto out_err; | ||
| 130 | clnt->cl_softrtry = 1; | ||
| 131 | clnt->cl_oneshot = 1; | ||
| 132 | return clnt; | ||
| 133 | |||
| 134 | out_err: | ||
| 135 | return clnt; | ||
| 136 | } | 129 | } |
| 137 | 130 | ||
| 138 | /* | 131 | /* |
| @@ -4,9 +4,9 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | obj-$(CONFIG_NFS_FS) += nfs.o | 5 | obj-$(CONFIG_NFS_FS) += nfs.o |
| 6 | 6 | ||
| 7 | nfs-y := dir.o file.o inode.o super.o nfs2xdr.o pagelist.o \ | 7 | nfs-y := client.o dir.o file.o getroot.o inode.o super.o nfs2xdr.o \ |
| 8 | proc.o read.o symlink.o unlink.o write.o \ | 8 | pagelist.o proc.o read.o symlink.o unlink.o \ |
| 9 | namespace.o | 9 | write.o namespace.o |
| 10 | nfs-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o | 10 | nfs-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o |
| 11 | nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o | 11 | nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o |
| 12 | nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o | 12 | nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | #include "nfs4_fs.h" | 20 | #include "nfs4_fs.h" |
| 21 | #include "callback.h" | 21 | #include "callback.h" |
| 22 | #include "internal.h" | ||
| 22 | 23 | ||
| 23 | #define NFSDBG_FACILITY NFSDBG_CALLBACK | 24 | #define NFSDBG_FACILITY NFSDBG_CALLBACK |
| 24 | 25 | ||
| @@ -36,6 +37,21 @@ static struct svc_program nfs4_callback_program; · 11 unmodified lines | |||
| 36 | 37 | ||
| 37 | unsigned int nfs_callback_set_tcpport; | 38 | unsigned int nfs_callback_set_tcpport; |
| 38 | unsigned short nfs_callback_tcpport; | 39 | unsigned short nfs_callback_tcpport; |
| 40 | static const int nfs_set_port_min = 0; | ||
| 41 | static const int nfs_set_port_max = 65535; | ||
| 42 | |||
| 43 | static int param_set_port(const char *val, struct kernel_param *kp) | ||
| 44 | { | ||
| 45 | char *endp; | ||
| 46 | int num = simple_strtol(val, &endp, 0); | ||
| 47 | if (endp == val || *endp || num < nfs_set_port_min || num > nfs_set_port_max) | ||
| 48 | return -EINVAL; | ||
| 49 | *((int *)kp->arg) = num; | ||
| 50 | return 0; | ||
| 51 | } | ||
| 52 | |||
| 53 | module_param_call(callback_tcpport, param_set_port, param_get_int, | ||
| 54 | &nfs_callback_set_tcpport, 0644); | ||
| 39 | 55 | ||
| 40 | /* | 56 | /* |
| 41 | * This is the callback kernel thread. | 57 | * This is the callback kernel thread. |
| @@ -134,10 +150,8 @@ out_err: · 92 unmodified lines | |||
| 134 | /* | 150 | /* |
| 135 | * Kill the server process if it is not already up. | 151 | * Kill the server process if it is not already up. |
| 136 | */ | 152 | */ |
| 137 | int nfs_callback_down(void) | 153 | void nfs_callback_down(void) |
| 138 | { | 154 | { |
| 139 | int ret = 0; | ||
| 140 | |||
| 141 | lock_kernel(); | 155 | lock_kernel(); |
| 142 | mutex_lock(&nfs_callback_mutex); | 156 | mutex_lock(&nfs_callback_mutex); |
| 143 | nfs_callback_info.users--; | 157 | nfs_callback_info.users--; |
| @@ -149,20 +163,19 @@ int nfs_callback_down(void) · 5 unmodified lines | |||
| 149 | } while (wait_for_completion_timeout(&nfs_callback_info.stopped, 5*HZ) == 0); | 163 | } while (wait_for_completion_timeout(&nfs_callback_info.stopped, 5*HZ) == 0); |
| 150 | mutex_unlock(&nfs_callback_mutex); | 164 | mutex_unlock(&nfs_callback_mutex); |
| 151 | unlock_kernel(); | 165 | unlock_kernel(); |
| 152 | return ret; | ||
| 153 | } | 166 | } |
| 154 | 167 | ||
| 155 | static int nfs_callback_authenticate(struct svc_rqst *rqstp) | 168 | static int nfs_callback_authenticate(struct svc_rqst *rqstp) |
| 156 | { | 169 | { |
| 157 | struct in_addr *addr = &rqstp->rq_addr.sin_addr; | 170 | struct sockaddr_in *addr = &rqstp->rq_addr; |
| 158 | struct nfs4_client *clp; | 171 | struct nfs_client *clp; |
| 159 | 172 | ||
| 160 | /* Don't talk to strangers */ | 173 | /* Don't talk to strangers */ |
| 161 | clp = nfs4_find_client(addr); | 174 | clp = nfs_find_client(addr, 4); |
| 162 | if (clp == NULL) | 175 | if (clp == NULL) |
| 163 | return SVC_DROP; | 176 | return SVC_DROP; |
| 164 | dprintk("%s: %u.%u.%u.%u NFSv4 callback!\n", __FUNCTION__, NIPQUAD(addr)); | 177 | dprintk("%s: %u.%u.%u.%u NFSv4 callback!\n", __FUNCTION__, NIPQUAD(addr->sin_addr)); |
| 165 | nfs4_put_client(clp); | 178 | nfs_put_client(clp); |
| 166 | switch (rqstp->rq_authop->flavour) { | 179 | switch (rqstp->rq_authop->flavour) { |
| 167 | case RPC_AUTH_NULL: | 180 | case RPC_AUTH_NULL: |
| 168 | if (rqstp->rq_proc != CB_NULL) | 181 | if (rqstp->rq_proc != CB_NULL) |
| @@ -62,8 +62,13 @@ struct cb_recallargs { · 61 unmodified lines | |||
| 62 | extern unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res); | 62 | extern unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res); |
| 63 | extern unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy); | 63 | extern unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy); |
| 64 | 64 | ||
| 65 | #ifdef CONFIG_NFS_V4 | ||
| 65 | extern int nfs_callback_up(void); | 66 | extern int nfs_callback_up(void); |
| 66 | extern int nfs_callback_down(void); | 67 | extern void nfs_callback_down(void); |
| 68 | #else | ||
| 69 | #define nfs_callback_up() (0) | ||
| 70 | #define nfs_callback_down() do {} while(0) | ||
| 71 | #endif | ||
| 67 | 72 | ||
| 68 | extern unsigned int nfs_callback_set_tcpport; | 73 | extern unsigned int nfs_callback_set_tcpport; |
| 69 | extern unsigned short nfs_callback_tcpport; | 74 | extern unsigned short nfs_callback_tcpport; |
| @@ -10,19 +10,20 @@ · 9 unmodified lines | |||
| 10 | #include "nfs4_fs.h" | 10 | #include "nfs4_fs.h" |
| 11 | #include "callback.h" | 11 | #include "callback.h" |
| 12 | #include "delegation.h" | 12 | #include "delegation.h" |
| 13 | #include "internal.h" | ||
| 13 | 14 | ||
| 14 | #define NFSDBG_FACILITY NFSDBG_CALLBACK | 15 | #define NFSDBG_FACILITY NFSDBG_CALLBACK |
| 15 | 16 | ||
| 16 | unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res) | 17 | unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res) |
| 17 | { | 18 | { |
| 18 | struct nfs4_client *clp; | 19 | struct nfs_client *clp; |
| 19 | struct nfs_delegation *delegation; | 20 | struct nfs_delegation *delegation; |
| 20 | struct nfs_inode *nfsi; | 21 | struct nfs_inode *nfsi; |
| 21 | struct inode *inode; | 22 | struct inode *inode; |
| 22 | 23 | ||
| 23 | res->bitmap[0] = res->bitmap[1] = 0; | 24 | res->bitmap[0] = res->bitmap[1] = 0; |
| 24 | res->status = htonl(NFS4ERR_BADHANDLE); | 25 | res->status = htonl(NFS4ERR_BADHANDLE); |
| 25 | clp = nfs4_find_client(&args->addr->sin_addr); | 26 | clp = nfs_find_client(args->addr, 4); |
| 26 | if (clp == NULL) | 27 | if (clp == NULL) |
| 27 | goto out; | 28 | goto out; |
| 28 | inode = nfs_delegation_find_inode(clp, &args->fh); | 29 | inode = nfs_delegation_find_inode(clp, &args->fh); |
| @@ -48,7 +49,7 @@ out_iput: · 19 unmodified lines | |||
| 48 | up_read(&nfsi->rwsem); | 49 | up_read(&nfsi->rwsem); |
| 49 | iput(inode); | 50 | iput(inode); |
| 50 | out_putclient: | 51 | out_putclient: |
| 51 | nfs4_put_client(clp); | 52 | nfs_put_client(clp); |
| 52 | out: | 53 | out: |
| 53 | dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res->status)); | 54 | dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res->status)); |
| 54 | return res->status; | 55 | return res->status; |
| @@ -56,12 +57,12 @@ out: · 1 unmodified line | |||
| 56 | 57 | ||
| 57 | unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy) | 58 | unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy) |
| 58 | { | 59 | { |
| 59 | struct nfs4_client *clp; | 60 | struct nfs_client *clp; |
| 60 | struct inode *inode; | 61 | struct inode *inode; |
| 61 | unsigned res; | 62 | unsigned res; |
| 62 | 63 | ||
| 63 | res = htonl(NFS4ERR_BADHANDLE); | 64 | res = htonl(NFS4ERR_BADHANDLE); |
| 64 | clp = nfs4_find_client(&args->addr->sin_addr); | 65 | clp = nfs_find_client(args->addr, 4); |
| 65 | if (clp == NULL) | 66 | if (clp == NULL) |
| 66 | goto out; | 67 | goto out; |
| 67 | inode = nfs_delegation_find_inode(clp, &args->fh); | 68 | inode = nfs_delegation_find_inode(clp, &args->fh); |
| @@ -80,7 +81,7 @@ unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy) · 12 unmodified lines | |||
| 80 | } | 81 | } |
| 81 | iput(inode); | 82 | iput(inode); |
| 82 | out_putclient: | 83 | out_putclient: |
| 83 | nfs4_put_client(clp); | 84 | nfs_put_client(clp); |
| 84 | out: | 85 | out: |
| 85 | dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res)); | 86 | dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res)); |
| 86 | return res; | 87 | return res; |
| @@ -0,0 +1,1448 @@ | |||
| 1 | /* client.c: NFS client sharing and management code | ||
| 2 | * | ||
| 3 | * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. | ||
| 4 | * Written by David Howells (dhowells@redhat.com) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | |||
| 13 | #include <linux/config.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | |||
| 17 | #include <linux/time.h> | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/mm.h> | ||
| 20 | #include <linux/string.h> | ||
| 21 | #include <linux/stat.h> | ||
| 22 | #include <linux/errno.h> | ||
| 23 | #include <linux/unistd.h> | ||
| 24 | #include <linux/sunrpc/clnt.h> | ||
| 25 | #include <linux/sunrpc/stats.h> | ||
| 26 | #include <linux/sunrpc/metrics.h> | ||
| 27 | #include <linux/nfs_fs.h> | ||
| 28 | #include <linux/nfs_mount.h> | ||
| 29 | #include <linux/nfs4_mount.h> | ||
| 30 | #include <linux/lockd/bind.h> | ||
| 31 | #include <linux/smp_lock.h> | ||
| 32 | #include <linux/seq_file.h> | ||
| 33 | #include <linux/mount.h> | ||
| 34 | #include <linux/nfs_idmap.h> | ||
| 35 | #include <linux/vfs.h> | ||
| 36 | #include <linux/inet.h> | ||
| 37 | #include <linux/nfs_xdr.h> | ||
| 38 | |||
| 39 | #include <asm/system.h> | ||
| 40 | |||
| 41 | #include "nfs4_fs.h" | ||
| 42 | #include "callback.h" | ||
| 43 | #include "delegation.h" | ||
| 44 | #include "iostat.h" | ||
| 45 | #include "internal.h" | ||
| 46 | |||
| 47 | #define NFSDBG_FACILITY NFSDBG_CLIENT | ||
| 48 | |||
| 49 | static DEFINE_SPINLOCK(nfs_client_lock); | ||
| 50 | static LIST_HEAD(nfs_client_list); | ||
| 51 | static LIST_HEAD(nfs_volume_list); | ||
| 52 | static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq); | ||
| 53 | |||
| 54 | /* | ||
| 55 | * RPC cruft for NFS | ||
| 56 | */ | ||
| 57 | static struct rpc_version *nfs_version[5] = { | ||
| 58 | [2] = &nfs_version2, | ||
| 59 | #ifdef CONFIG_NFS_V3 | ||
| 60 | [3] = &nfs_version3, | ||
| 61 | #endif | ||
| 62 | #ifdef CONFIG_NFS_V4 | ||
| 63 | [4] = &nfs_version4, | ||
| 64 | #endif | ||
| 65 | }; | ||
| 66 | |||
| 67 | struct rpc_program nfs_program = { | ||
| 68 | .name = "nfs", | ||
| 69 | .number = NFS_PROGRAM, | ||
| 70 | .nrvers = ARRAY_SIZE(nfs_version), | ||
| 71 | .version = nfs_version, | ||
| 72 | .stats = &nfs_rpcstat, | ||
| 73 | .pipe_dir_name = "/nfs", | ||
| 74 | }; | ||
| 75 | |||
| 76 | struct rpc_stat nfs_rpcstat = { | ||
| 77 | .program = &nfs_program | ||
| 78 | }; | ||
| 79 | |||
| 80 | |||
| 81 | #ifdef CONFIG_NFS_V3_ACL | ||
| 82 | static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program }; | ||
| 83 | static struct rpc_version * nfsacl_version[] = { | ||
| 84 | [3] = &nfsacl_version3, | ||
| 85 | }; | ||
| 86 | |||
| 87 | struct rpc_program nfsacl_program = { | ||
| 88 | .name = "nfsacl", | ||
| 89 | .number = NFS_ACL_PROGRAM, | ||
| 90 | .nrvers = ARRAY_SIZE(nfsacl_version), | ||
| 91 | .version = nfsacl_version, | ||
| 92 | .stats = &nfsacl_rpcstat, | ||
| 93 | }; | ||
| 94 | #endif /* CONFIG_NFS_V3_ACL */ | ||
| 95 | |||
| 96 | /* | ||
| 97 | * Allocate a shared client record | ||
| 98 | * | ||
| 99 | * Since these are allocated/deallocated very rarely, we don't | ||
| 100 | * bother putting them in a slab cache... | ||
| 101 | */ | ||
| 102 | static struct nfs_client *nfs_alloc_client(const char *hostname, | ||
| 103 | const struct sockaddr_in *addr, | ||
| 104 | int nfsversion) | ||
| 105 | { | ||
| 106 | struct nfs_client *clp; | ||
| 107 | int error; | ||
| 108 | |||
| 109 | if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) | ||
| 110 | goto error_0; | ||
| 111 | |||
| 112 | error = rpciod_up(); | ||
| 113 | if (error < 0) { | ||
| 114 | dprintk("%s: couldn't start rpciod! Error = %d\n", | ||
| 115 | __FUNCTION__, error); | ||
| 116 | goto error_1; | ||
| 117 | } | ||
| 118 | __set_bit(NFS_CS_RPCIOD, &clp->cl_res_state); | ||
| 119 | |||
| 120 | if (nfsversion == 4) { | ||
| 121 | if (nfs_callback_up() < 0) | ||
| 122 | goto error_2; | ||
| 123 | __set_bit(NFS_CS_CALLBACK, &clp->cl_res_state); | ||
| 124 | } | ||
| 125 | |||
| 126 | atomic_set(&clp->cl_count, 1); | ||
| 127 | clp->cl_cons_state = NFS_CS_INITING; | ||
| 128 | |||
| 129 | clp->cl_nfsversion = nfsversion; | ||
| 130 | memcpy(&clp->cl_addr, addr, sizeof(clp->cl_addr)); | ||
| 131 | |||
| 132 | if (hostname) { | ||
| 133 | clp->cl_hostname = kstrdup(hostname, GFP_KERNEL); | ||
| 134 | if (!clp->cl_hostname) | ||
| 135 | goto error_3; | ||
| 136 | } | ||
| 137 | |||
| 138 | INIT_LIST_HEAD(&clp->cl_superblocks); | ||
| 139 | clp->cl_rpcclient = ERR_PTR(-EINVAL); | ||
| 140 | |||
| 141 | #ifdef CONFIG_NFS_V4 | ||
| 142 | init_rwsem(&clp->cl_sem); | ||
| 143 | INIT_LIST_HEAD(&clp->cl_delegations); | ||
| 144 | INIT_LIST_HEAD(&clp->cl_state_owners); | ||
| 145 | INIT_LIST_HEAD(&clp->cl_unused); | ||
| 146 | spin_lock_init(&clp->cl_lock); | ||
| 147 | INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); | ||
| 148 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); | ||
| 149 | clp->cl_boot_time = CURRENT_TIME; | ||
| 150 | clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; | ||
| 151 | #endif | ||
| 152 | |||
| 153 | return clp; | ||
| 154 | |||
| 155 | error_3: | ||
| 156 | if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state)) | ||
| 157 | nfs_callback_down(); | ||
| 158 | error_2: | ||
| 159 | rpciod_down(); | ||
| 160 | __clear_bit(NFS_CS_RPCIOD, &clp->cl_res_state); | ||
| 161 | error_1: | ||
| 162 | kfree(clp); | ||
| 163 | error_0: | ||
| 164 | return NULL; | ||
| 165 | } | ||
| 166 | |||
| 167 | static void nfs4_shutdown_client(struct nfs_client *clp) | ||
| 168 | { | ||
| 169 | #ifdef CONFIG_NFS_V4 | ||
| 170 | if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state)) | ||
| 171 | nfs4_kill_renewd(clp); | ||
| 172 | while (!list_empty(&clp->cl_unused)) { | ||
| 173 | struct nfs4_state_owner *sp; | ||
| 174 | |||
| 175 | sp = list_entry(clp->cl_unused.next, | ||
| 176 | struct nfs4_state_owner, | ||
| 177 | so_list); | ||
| 178 | list_del(&sp->so_list); | ||
| 179 | kfree(sp); | ||
| 180 | } | ||
| 181 | BUG_ON(!list_empty(&clp->cl_state_owners)); | ||
| 182 | if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state)) | ||
| 183 | nfs_idmap_delete(clp); | ||
| 184 | #endif | ||
| 185 | } | ||
| 186 | |||
| 187 | /* | ||
| 188 | * Destroy a shared client record | ||
| 189 | */ | ||
| 190 | static void nfs_free_client(struct nfs_client *clp) | ||
| 191 | { | ||
| 192 | dprintk("--> nfs_free_client(%d)\n", clp->cl_nfsversion); | ||
| 193 | |||
| 194 | nfs4_shutdown_client(clp); | ||
| 195 | |||
| 196 | /* -EIO all pending I/O */ | ||
| 197 | if (!IS_ERR(clp->cl_rpcclient)) | ||
| 198 | rpc_shutdown_client(clp->cl_rpcclient); | ||
| 199 | |||
| 200 | if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state)) | ||
| 201 | nfs_callback_down(); | ||
| 202 | |||
| 203 | if (__test_and_clear_bit(NFS_CS_RPCIOD, &clp->cl_res_state)) | ||
| 204 | rpciod_down(); | ||
| 205 | |||
| 206 | kfree(clp->cl_hostname); | ||
| 207 | kfree(clp); | ||
| 208 | |||
| 209 | dprintk("<-- nfs_free_client()\n"); | ||
| 210 | } | ||
| 211 | |||
| 212 | /* | ||
| 213 | * Release a reference to a shared client record | ||
| 214 | */ | ||
| 215 | void nfs_put_client(struct nfs_client *clp) | ||
| 216 | { | ||
| 217 | if (!clp) | ||
| 218 | return; | ||
| 219 | |||
| 220 | dprintk("--> nfs_put_client({%d})\n", atomic_read(&clp->cl_count)); | ||
| 221 | |||
| 222 | if (atomic_dec_and_lock(&clp->cl_count, &nfs_client_lock)) { | ||
| 223 | list_del(&clp->cl_share_link); | ||
| 224 | spin_unlock(&nfs_client_lock); | ||
| 225 | |||
| 226 | BUG_ON(!list_empty(&clp->cl_superblocks)); | ||
| 227 | |||
| 228 | nfs_free_client(clp); | ||
| 229 | } | ||
| 230 | } | ||
| 231 | |||
| 232 | /* | ||
| 233 | * Find a client by address | ||
| 234 | * - caller must hold nfs_client_lock | ||
| 235 | */ | ||
| 236 | static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion) | ||
| 237 | { | ||
| 238 | struct nfs_client *clp; | ||
| 239 | |||
| 240 | list_for_each_entry(clp, &nfs_client_list, cl_share_link) { | ||
| 241 | /* Different NFS versions cannot share the same nfs_client */ | ||
| 242 | if (clp->cl_nfsversion != nfsversion) | ||
| 243 | continue; | ||
| 244 | |||
| 245 | if (memcmp(&clp->cl_addr.sin_addr, &addr->sin_addr, | ||
| 246 | sizeof(clp->cl_addr.sin_addr)) != 0) | ||
| 247 | continue; | ||
| 248 | |||
| 249 | if (clp->cl_addr.sin_port == addr->sin_port) | ||
| 250 | goto found; | ||
| 251 | } | ||
| 252 | |||
| 253 | return NULL; | ||
| 254 | |||
| 255 | found: | ||
| 256 | atomic_inc(&clp->cl_count); | ||
| 257 | return clp; | ||
| 258 | } | ||
| 259 | |||
| 260 | /* | ||
| 261 | * Find a client by IP address and protocol version | ||
| 262 | * - returns NULL if no such client | ||
| 263 | */ | ||
| 264 | struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversion) | ||
| 265 | { | ||
| 266 | struct nfs_client *clp; | ||
| 267 | |||
| 268 | spin_lock(&nfs_client_lock); | ||
| 269 | clp = __nfs_find_client(addr, nfsversion); | ||
| 270 | spin_unlock(&nfs_client_lock); | ||
| 271 | |||
| 272 | BUG_ON(clp && clp->cl_cons_state == 0); | ||
| 273 | |||
| 274 | return clp; | ||
| 275 | } | ||
| 276 | |||
| 277 | /* | ||
| 278 | * Look up a client by IP address and protocol version | ||
| 279 | * - creates a new record if one doesn't yet exist | ||
| 280 | */ | ||
| 281 | static struct nfs_client *nfs_get_client(const char *hostname, | ||
| 282 | const struct sockaddr_in *addr, | ||
| 283 | int nfsversion) | ||
| 284 | { | ||
| 285 | struct nfs_client *clp, *new = NULL; | ||
| 286 | int error; | ||
| 287 | |||
| 288 | dprintk("--> nfs_get_client(%s,"NIPQUAD_FMT":%d,%d)\n", | ||
| 289 | hostname ?: "", NIPQUAD(addr->sin_addr), | ||
| 290 | addr->sin_port, nfsversion); | ||
| 291 | |||
| 292 | /* see if the client already exists */ | ||
| 293 | do { | ||
| 294 | spin_lock(&nfs_client_lock); | ||
| 295 | |||
| 296 | clp = __nfs_find_client(addr, nfsversion); | ||
| 297 | if (clp) | ||
| 298 | goto found_client; | ||
| 299 | if (new) | ||
| 300 | goto install_client; | ||
| 301 | |||
| 302 | spin_unlock(&nfs_client_lock); | ||
| 303 | |||
| 304 | new = nfs_alloc_client(hostname, addr, nfsversion); | ||
| 305 | } while (new); | ||
| 306 | |||
| 307 | return ERR_PTR(-ENOMEM); | ||
| 308 | |||
| 309 | /* install a new client and return with it unready */ | ||
| 310 | install_client: | ||
| 311 | clp = new; | ||
| 312 | list_add(&clp->cl_share_link, &nfs_client_list); | ||
| 313 | spin_unlock(&nfs_client_lock); | ||
| 314 | dprintk("--> nfs_get_client() = %p [new]\n", clp); | ||
| 315 | return clp; | ||
| 316 | |||
| 317 | /* found an existing client | ||
| 318 | * - make sure it's ready before returning | ||
| 319 | */ | ||
| 320 | found_client: | ||
| 321 | spin_unlock(&nfs_client_lock); | ||
| 322 | |||
| 323 | if (new) | ||
| 324 | nfs_free_client(new); | ||
| 325 | |||
| 326 | if (clp->cl_cons_state == NFS_CS_INITING) { | ||
| 327 | DECLARE_WAITQUEUE(myself, current); | ||
| 328 | |||
| 329 | add_wait_queue(&nfs_client_active_wq, &myself); | ||
| 330 | |||
| 331 | for (;;) { | ||
| 332 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 333 | if (signal_pending(current) || | ||
| 334 | clp->cl_cons_state > NFS_CS_READY) | ||
| 335 | break; | ||
| 336 | schedule(); | ||
| 337 | } | ||
| 338 | |||
| 339 | remove_wait_queue(&nfs_client_active_wq, &myself); | ||
| 340 | |||
| 341 | if (signal_pending(current)) { | ||
| 342 | nfs_put_client(clp); | ||
| 343 | return ERR_PTR(-ERESTARTSYS); | ||
| 344 | } | ||
| 345 | } | ||
| 346 | |||
| 347 | if (clp->cl_cons_state < NFS_CS_READY) { | ||
| 348 | error = clp->cl_cons_state; | ||
| 349 | nfs_put_client(clp); | ||
| 350 | return ERR_PTR(error); | ||
| 351 | } | ||
| 352 | |||
| 353 | BUG_ON(clp->cl_cons_state != NFS_CS_READY); | ||
| 354 | |||
| 355 | dprintk("--> nfs_get_client() = %p [share]\n", clp); | ||
| 356 | return clp; | ||
| 357 | } | ||
| 358 | |||
| 359 | /* | ||
| 360 | * Mark a server as ready or failed | ||
| 361 | */ | ||
| 362 | static void nfs_mark_client_ready(struct nfs_client *clp, int state) | ||
| 363 | { | ||
| 364 | clp->cl_cons_state = state; | ||
| 365 | wake_up_all(&nfs_client_active_wq); | ||
| 366 | } | ||
| 367 | |||
| 368 | /* | ||
| 369 | * Initialise the timeout values for a connection | ||
| 370 | */ | ||
| 371 | static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, | ||
| 372 | unsigned int timeo, unsigned int retrans) | ||
| 373 | { | ||
| 374 | to->to_initval = timeo * HZ / 10; | ||
| 375 | to->to_retries = retrans; | ||
| 376 | if (!to->to_retries) | ||
| 377 | to->to_retries = 2; | ||
| 378 | |||
| 379 | switch (proto) { | ||
| 380 | case IPPROTO_TCP: | ||
| 381 | if (!to->to_initval) | ||
| 382 | to->to_initval = 60 * HZ; | ||
| 383 | if (to->to_initval > NFS_MAX_TCP_TIMEOUT) | ||
| 384 | to->to_initval = NFS_MAX_TCP_TIMEOUT; | ||
| 385 | to->to_increment = to->to_initval; | ||
| 386 | to->to_maxval = to->to_initval + (to->to_increment * to->to_retries); | ||
| 387 | to->to_exponential = 0; | ||
| 388 | break; | ||
| 389 | case IPPROTO_UDP: | ||
| 390 | default: | ||
| 391 | if (!to->to_initval) | ||
| 392 | to->to_initval = 11 * HZ / 10; | ||
| 393 | if (to->to_initval > NFS_MAX_UDP_TIMEOUT) | ||
| 394 | to->to_initval = NFS_MAX_UDP_TIMEOUT; | ||
| 395 | to->to_maxval = NFS_MAX_UDP_TIMEOUT; | ||
| 396 | to->to_exponential = 1; | ||
| 397 | break; | ||
| 398 | } | ||
| 399 | } | ||
| 400 | |||
| 401 | /* | ||
| 402 | * Create an RPC client handle | ||
| 403 | */ | ||
| 404 | static int nfs_create_rpc_client(struct nfs_client *clp, int proto, | ||
| 405 | unsigned int timeo, | ||
| 406 | unsigned int retrans, | ||
| 407 | rpc_authflavor_t flavor) | ||
| 408 | { | ||
| 409 | struct rpc_timeout timeparms; | ||
| 410 | struct rpc_clnt *clnt = NULL; | ||
| 411 | struct rpc_create_args args = { | ||
| 412 | .protocol = proto, | ||
| 413 | .address = (struct sockaddr *)&clp->cl_addr, | ||
| 414 | .addrsize = sizeof(clp->cl_addr), | ||
| 415 | .timeout = &timeparms, | ||
| 416 | .servername = clp->cl_hostname, | ||
| 417 | .program = &nfs_program, | ||
| 418 | .version = clp->rpc_ops->version, | ||
| 419 | .authflavor = flavor, | ||
| 420 | }; | ||
| 421 | |||
| 422 | if (!IS_ERR(clp->cl_rpcclient)) | ||
| 423 | return 0; | ||
| 424 | |||
| 425 | nfs_init_timeout_values(&timeparms, proto, timeo, retrans); | ||
| 426 | clp->retrans_timeo = timeparms.to_initval; | ||
| 427 | clp->retrans_count = timeparms.to_retries; | ||
| 428 | |||
| 429 | clnt = rpc_create(&args); | ||
| 430 | if (IS_ERR(clnt)) { | ||
| 431 | dprintk("%s: cannot create RPC client. Error = %ld\n", | ||
| 432 | __FUNCTION__, PTR_ERR(clnt)); | ||
| 433 | return PTR_ERR(clnt); | ||
| 434 | } | ||
| 435 | |||
| 436 | clp->cl_rpcclient = clnt; | ||
| 437 | return 0; | ||
| 438 | } | ||
| 439 | |||
| 440 | /* | ||
| 441 | * Version 2 or 3 client destruction | ||
| 442 | */ | ||
| 443 | static void nfs_destroy_server(struct nfs_server *server) | ||
| 444 | { | ||
| 445 | if (!IS_ERR(server->client_acl)) | ||
| 446 | rpc_shutdown_client(server->client_acl); | ||
| 447 | |||
| 448 | if (!(server->flags & NFS_MOUNT_NONLM)) | ||
| 449 | lockd_down(); /* release rpc.lockd */ | ||
| 450 | } | ||
| 451 | |||
| 452 | /* | ||
| 453 | * Version 2 or 3 lockd setup | ||
| 454 | */ | ||
| 455 | static int nfs_start_lockd(struct nfs_server *server) | ||
| 456 | { | ||
| 457 | int error = 0; | ||
| 458 | |||
| 459 | if (server->nfs_client->cl_nfsversion > 3) | ||
| 460 | goto out; | ||
| 461 | if (server->flags & NFS_MOUNT_NONLM) | ||
| 462 | goto out; | ||
| 463 | error = lockd_up(); | ||
| 464 | if (error < 0) | ||
| 465 | server->flags |= NFS_MOUNT_NONLM; | ||
| 466 | else | ||
| 467 | server->destroy = nfs_destroy_server; | ||
| 468 | out: | ||
| 469 | return error; | ||
| 470 | } | ||
| 471 | |||
| 472 | /* | ||
| 473 | * Initialise an NFSv3 ACL client connection | ||
| 474 | */ | ||
| 475 | #ifdef CONFIG_NFS_V3_ACL | ||
| 476 | static void nfs_init_server_aclclient(struct nfs_server *server) | ||
| 477 | { | ||
| 478 | if (server->nfs_client->cl_nfsversion != 3) | ||
| 479 | goto out_noacl; | ||
| 480 | if (server->flags & NFS_MOUNT_NOACL) | ||
| 481 | goto out_noacl; | ||
| 482 | |||
| 483 | server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3); | ||
| 484 | if (IS_ERR(server->client_acl)) | ||
| 485 | goto out_noacl; | ||
| 486 | |||
| 487 | /* No errors! Assume that Sun nfsacls are supported */ | ||
| 488 | server->caps |= NFS_CAP_ACLS; | ||
| 489 | return; | ||
| 490 | |||
| 491 | out_noacl: | ||
| 492 | server->caps &= ~NFS_CAP_ACLS; | ||
| 493 | } | ||
| 494 | #else | ||
| 495 | static inline void nfs_init_server_aclclient(struct nfs_server *server) | ||
| 496 | { | ||
| 497 | server->flags &= ~NFS_MOUNT_NOACL; | ||
| 498 | server->caps &= ~NFS_CAP_ACLS; | ||
| 499 | } | ||
| 500 | #endif | ||
| 501 | |||
| 502 | /* | ||
| 503 | * Create a general RPC client | ||
| 504 | */ | ||
| 505 | static int nfs_init_server_rpcclient(struct nfs_server *server, rpc_authflavor_t pseudoflavour) | ||
| 506 | { | ||
| 507 | struct nfs_client *clp = server->nfs_client; | ||
| 508 | |||
| 509 | server->client = rpc_clone_client(clp->cl_rpcclient); | ||
| 510 | if (IS_ERR(server->client)) { | ||
| 511 | dprintk("%s: couldn't create rpc_client!\n", __FUNCTION__); | ||
| 512 | return PTR_ERR(server->client); | ||
| 513 | } | ||
| 514 | |||
| 515 | if (pseudoflavour != clp->cl_rpcclient->cl_auth->au_flavor) { | ||
| 516 | struct rpc_auth *auth; | ||
| 517 | |||
| 518 | auth = rpcauth_create(pseudoflavour, server->client); | ||
| 519 | if (IS_ERR(auth)) { | ||
| 520 | dprintk("%s: couldn't create credcache!\n", __FUNCTION__); | ||
| 521 | return PTR_ERR(auth); | ||
| 522 | } | ||
| 523 | } | ||
| 524 | server->client->cl_softrtry = 0; | ||
| 525 | if (server->flags & NFS_MOUNT_SOFT) | ||
| 526 | server->client->cl_softrtry = 1; | ||
| 527 | |||
| 528 | server->client->cl_intr = 0; | ||
| 529 | if (server->flags & NFS4_MOUNT_INTR) | ||
| 530 | server->client->cl_intr = 1; | ||
| 531 | |||
| 532 | return 0; | ||
| 533 | } | ||
| 534 | |||
| 535 | /* | ||
| 536 | * Initialise an NFS2 or NFS3 client | ||
| 537 | */ | ||
| 538 | static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *data) | ||
| 539 | { | ||
| 540 | int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP; | ||
| 541 | int error; | ||
| 542 | |||
| 543 | if (clp->cl_cons_state == NFS_CS_READY) { | ||
| 544 | /* the client is already initialised */ | ||
| 545 | dprintk("<-- nfs_init_client() = 0 [already %p]\n", clp); | ||
| 546 | return 0; | ||
| 547 | } | ||
| 548 | |||
| 549 | /* Check NFS protocol revision and initialize RPC op vector */ | ||
| 550 | clp->rpc_ops = &nfs_v2_clientops; | ||
| 551 | #ifdef CONFIG_NFS_V3 | ||
| 552 | if (clp->cl_nfsversion == 3) | ||
| 553 | clp->rpc_ops = &nfs_v3_clientops; | ||
| 554 | #endif | ||
| 555 | /* | ||
| 556 | * Create a client RPC handle for doing FSSTAT with UNIX auth only | ||
| 557 | * - RFC 2623, sec 2.3.2 | ||
| 558 | */ | ||
| 559 | error = nfs_create_rpc_client(clp, proto, data->timeo, data->retrans, | ||
| 560 | RPC_AUTH_UNIX); | ||
| 561 | if (error < 0) | ||
| 562 | goto error; | ||
| 563 | nfs_mark_client_ready(clp, NFS_CS_READY); | ||
| 564 | return 0; | ||
| 565 | |||
| 566 | error: | ||
| 567 | nfs_mark_client_ready(clp, error); | ||
| 568 | dprintk("<-- nfs_init_client() = xerror %d\n", error); | ||
| 569 | return error; | ||
| 570 | } | ||
| 571 | |||
| 572 | /* | ||
| 573 | * Create a version 2 or 3 client | ||
| 574 | */ | ||
| 575 | static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_data *data) | ||
| 576 | { | ||
| 577 | struct nfs_client *clp; | ||
| 578 | int error, nfsvers = 2; | ||
| 579 | |||
| 580 | dprintk("--> nfs_init_server()\n"); | ||
| 581 | |||
| 582 | #ifdef CONFIG_NFS_V3 | ||
| 583 | if (data->flags & NFS_MOUNT_VER3) | ||
| 584 | nfsvers = 3; | ||
| 585 | #endif | ||
| 586 | |||
| 587 | /* Allocate or find a client reference we can use */ | ||
| 588 | clp = nfs_get_client(data->hostname, &data->addr, nfsvers); | ||
| 589 | if (IS_ERR(clp)) { | ||
| 590 | dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp)); | ||
| 591 | return PTR_ERR(clp); | ||
| 592 | } | ||
| 593 | |||
| 594 | error = nfs_init_client(clp, data); | ||
| 595 | if (error < 0) | ||
| 596 | goto error; | ||
| 597 | |||
| 598 | server->nfs_client = clp; | ||
| 599 | |||
| 600 | /* Initialise the client representation from the mount data */ | ||
| 601 | server->flags = data->flags & NFS_MOUNT_FLAGMASK; | ||
| 602 | |||
| 603 | if (data->rsize) | ||
| 604 | server->rsize = nfs_block_size(data->rsize, NULL); | ||
| 605 | if (data->wsize) | ||
| 606 | server->wsize = nfs_block_size(data->wsize, NULL); | ||
| 607 | |||
| 608 | server->acregmin = data->acregmin * HZ; | ||
| 609 | server->acregmax = data->acregmax * HZ; | ||
| 610 | server->acdirmin = data->acdirmin * HZ; | ||
| 611 | server->acdirmax = data->acdirmax * HZ; | ||
| 612 | |||
| 613 | /* Start lockd here, before we might error out */ | ||
| 614 | error = nfs_start_lockd(server); | ||
| 615 | if (error < 0) | ||
| 616 | goto error; | ||
| 617 | |||
| 618 | error = nfs_init_server_rpcclient(server, data->pseudoflavor); | ||
| 619 | if (error < 0) | ||
| 620 | goto error; | ||
| 621 | |||
| 622 | server->namelen = data->namlen; | ||
| 623 | /* Create a client RPC handle for the NFSv3 ACL management interface */ | ||
| 624 | nfs_init_server_aclclient(server); | ||
| 625 | if (clp->cl_nfsversion == 3) { | ||
| 626 | if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) | ||
| 627 | server->namelen = NFS3_MAXNAMLEN; | ||
| 628 | server->caps |= NFS_CAP_READDIRPLUS; | ||
| 629 | } else { | ||
| 630 | if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN) | ||
| 631 | server->namelen = NFS2_MAXNAMLEN; | ||
| 632 | } | ||
| 633 | |||
| 634 | dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp); | ||
| 635 | return 0; | ||
| 636 | |||
| 637 | error: | ||
| 638 | server->nfs_client = NULL; | ||
| 639 | nfs_put_client(clp); | ||
| 640 | dprintk("<-- nfs_init_server() = xerror %d\n", error); | ||
| 641 | return error; | ||
| 642 | } | ||
| 643 | |||
| 644 | /* | ||
| 645 | * Load up the server record from information gained in an fsinfo record | ||
| 646 | */ | ||
| 647 | static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *fsinfo) | ||
| 648 | { | ||
| 649 | unsigned long max_rpc_payload; | ||
| 650 | |||
| 651 | /* Work out a lot of parameters */ | ||
| 652 | if (server->rsize == 0) | ||
| 653 | server->rsize = nfs_block_size(fsinfo->rtpref, NULL); | ||
| 654 | if (server->wsize == 0) | ||
| 655 | server->wsize = nfs_block_size(fsinfo->wtpref, NULL); | ||
| 656 | |||
| 657 | if (fsinfo->rtmax >= 512 && server->rsize > fsinfo->rtmax) | ||
| 658 | server->rsize = nfs_block_size(fsinfo->rtmax, NULL); | ||
| 659 | if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax) | ||
| 660 | server->wsize = nfs_block_size(fsinfo->wtmax, NULL); | ||
| 661 | |||
| 662 | max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL); | ||
| 663 | if (server->rsize > max_rpc_payload) | ||
| 664 | server->rsize = max_rpc_payload; | ||
| 665 | if (server->rsize > NFS_MAX_FILE_IO_SIZE) | ||
| 666 | server->rsize = NFS_MAX_FILE_IO_SIZE; | ||
| 667 | server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | ||
| 668 | server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD; | ||
| 669 | |||
| 670 | if (server->wsize > max_rpc_payload) | ||
| 671 | server->wsize = max_rpc_payload; | ||
| 672 | if (server->wsize > NFS_MAX_FILE_IO_SIZE) | ||
| 673 | server->wsize = NFS_MAX_FILE_IO_SIZE; | ||
| 674 | server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | ||
| 675 | server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL); | ||
| 676 | |||
| 677 | server->dtsize = nfs_block_size(fsinfo->dtpref, NULL); | ||
| 678 | if (server->dtsize > PAGE_CACHE_SIZE) | ||
| 679 | server->dtsize = PAGE_CACHE_SIZE; | ||
| 680 | if (server->dtsize > server->rsize) | ||
| 681 | server->dtsize = server->rsize; | ||
| 682 | |||
| 683 | if (server->flags & NFS_MOUNT_NOAC) { | ||
| 684 | server->acregmin = server->acregmax = 0; | ||
| 685 | server->acdirmin = server->acdirmax = 0; | ||
| 686 | } | ||
| 687 | |||
| 688 | server->maxfilesize = fsinfo->maxfilesize; | ||
| 689 | |||
| 690 | /* We're airborne Set socket buffersize */ | ||
| 691 | rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100); | ||
| 692 | } | ||
| 693 | |||
| 694 | /* | ||
| 695 | * Probe filesystem information, including the FSID on v2/v3 | ||
| 696 | */ | ||
| 697 | static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr) | ||
| 698 | { | ||
| 699 | struct nfs_fsinfo fsinfo; | ||
| 700 | struct nfs_client *clp = server->nfs_client; | ||
| 701 | int error; | ||
| 702 | |||
| 703 | dprintk("--> nfs_probe_fsinfo()\n"); | ||
| 704 | |||
| 705 | if (clp->rpc_ops->set_capabilities != NULL) { | ||
| 706 | error = clp->rpc_ops->set_capabilities(server, mntfh); | ||
| 707 | if (error < 0) | ||
| 708 | goto out_error; | ||
| 709 | } | ||
| 710 | |||
| 711 | fsinfo.fattr = fattr; | ||
| 712 | nfs_fattr_init(fattr); | ||
| 713 | error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo); | ||
| 714 | if (error < 0) | ||
| 715 | goto out_error; | ||
| 716 | |||
| 717 | nfs_server_set_fsinfo(server, &fsinfo); | ||
| 718 | |||
| 719 | /* Get some general file system info */ | ||
| 720 | if (server->namelen == 0) { | ||
| 721 | struct nfs_pathconf pathinfo; | ||
| 722 | |||
| 723 | pathinfo.fattr = fattr; | ||
| 724 | nfs_fattr_init(fattr); | ||
| 725 | |||
| 726 | if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0) | ||
| 727 | server->namelen = pathinfo.max_namelen; | ||
| 728 | } | ||
| 729 | |||
| 730 | dprintk("<-- nfs_probe_fsinfo() = 0\n"); | ||
| 731 | return 0; | ||
| 732 | |||
| 733 | out_error: | ||
| 734 | dprintk("nfs_probe_fsinfo: error = %d\n", -error); | ||
| 735 | return error; | ||
| 736 | } | ||
| 737 | |||
| 738 | /* | ||
| 739 | * Copy useful information when duplicating a server record | ||
| 740 | */ | ||
| 741 | static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source) | ||
| 742 | { | ||
| 743 | target->flags = source->flags; | ||
| 744 | target->acregmin = source->acregmin; | ||
| 745 | target->acregmax = source->acregmax; | ||
| 746 | target->acdirmin = source->acdirmin; | ||
| 747 | target->acdirmax = source->acdirmax; | ||
| 748 | target->caps = source->caps; | ||
| 749 | } | ||
| 750 | |||
| 751 | /* | ||
| 752 | * Allocate and initialise a server record | ||
| 753 | */ | ||
| 754 | static struct nfs_server *nfs_alloc_server(void) | ||
| 755 | { | ||
| 756 | struct nfs_server *server; | ||
| 757 | |||
| 758 | server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); | ||
| 759 | if (!server) | ||
| 760 | return NULL; | ||
| 761 | |||
| 762 | server->client = server->client_acl = ERR_PTR(-EINVAL); | ||
| 763 | |||
| 764 | /* Zero out the NFS state stuff */ | ||
| 765 | INIT_LIST_HEAD(&server->client_link); | ||
| 766 | INIT_LIST_HEAD(&server->master_link); | ||
| 767 | |||
| 768 | server->io_stats = nfs_alloc_iostats(); | ||
| 769 | if (!server->io_stats) { | ||
| 770 | kfree(server); | ||
| 771 | return NULL; | ||
| 772 | } | ||
| 773 | |||
| 774 | return server; | ||
| 775 | } | ||
| 776 | |||
| 777 | /* | ||
| 778 | * Free up a server record | ||
| 779 | */ | ||
| 780 | void nfs_free_server(struct nfs_server *server) | ||
| 781 | { | ||
| 782 | dprintk("--> nfs_free_server()\n"); | ||
| 783 | |||
| 784 | spin_lock(&nfs_client_lock); | ||
| 785 | list_del(&server->client_link); | ||
| 786 | list_del(&server->master_link); | ||
| 787 | spin_unlock(&nfs_client_lock); | ||
| 788 | |||
| 789 | if (server->destroy != NULL) | ||
| 790 | server->destroy(server); | ||
| 791 | if (!IS_ERR(server->client)) | ||
| 792 | rpc_shutdown_client(server->client); | ||
| 793 | |||
| 794 | nfs_put_client(server->nfs_client); | ||
| 795 | |||
| 796 | nfs_free_iostats(server->io_stats); | ||
| 797 | kfree(server); | ||
| 798 | nfs_release_automount_timer(); | ||
| 799 | dprintk("<-- nfs_free_server()\n"); | ||
| 800 | } | ||
| 801 | |||
| 802 | /* | ||
| 803 | * Create a version 2 or 3 volume record | ||
| 804 | * - keyed on server and FSID | ||
| 805 | */ | ||
| 806 | struct nfs_server *nfs_create_server(const struct nfs_mount_data *data, | ||
| 807 | struct nfs_fh *mntfh) | ||
| 808 | { | ||
| 809 | struct nfs_server *server; | ||
| 810 | struct nfs_fattr fattr; | ||
| 811 | int error; | ||
| 812 | |||
| 813 | server = nfs_alloc_server(); | ||
| 814 | if (!server) | ||
| 815 | return ERR_PTR(-ENOMEM); | ||
| 816 | |||
| 817 | /* Get a client representation */ | ||
| 818 | error = nfs_init_server(server, data); | ||
| 819 | if (error < 0) | ||
| 820 | goto error; | ||
| 821 | |||
| 822 | BUG_ON(!server->nfs_client); | ||
| 823 | BUG_ON(!server->nfs_client->rpc_ops); | ||
| 824 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); | ||
| 825 | |||
| 826 | /* Probe the root fh to retrieve its FSID */ | ||
| 827 | error = nfs_probe_fsinfo(server, mntfh, &fattr); | ||
| 828 | if (error < 0) | ||
| 829 | goto error; | ||
| 830 | if (!(fattr.valid & NFS_ATTR_FATTR)) { | ||
| 831 | error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr); | ||
| 832 | if (error < 0) { | ||
| 833 | dprintk("nfs_create_server: getattr error = %d\n", -error); | ||
| 834 | goto error; | ||
| 835 | } | ||
| 836 | } | ||
| 837 | memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid)); | ||
| 838 | |||
| 839 | dprintk("Server FSID: %llx:%llx\n", | ||
| 840 | (unsigned long long) server->fsid.major, | ||
| 841 | (unsigned long long) server->fsid.minor); | ||
| 842 | |||
| 843 | BUG_ON(!server->nfs_client); | ||
| 844 | BUG_ON(!server->nfs_client->rpc_ops); | ||
| 845 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); | ||
| 846 | |||
| 847 | spin_lock(&nfs_client_lock); | ||
| 848 | list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); | ||
| 849 | list_add_tail(&server->master_link, &nfs_volume_list); | ||
| 850 | spin_unlock(&nfs_client_lock); | ||
| 851 | |||
| 852 | server->mount_time = jiffies; | ||
| 853 | return server; | ||
| 854 | |||
| 855 | error: | ||
| 856 | nfs_free_server(server); | ||
| 857 | return ERR_PTR(error); | ||
| 858 | } | ||
| 859 | |||
| 860 | #ifdef CONFIG_NFS_V4 | ||
| 861 | /* | ||
| 862 | * Initialise an NFS4 client record | ||
| 863 | */ | ||
| 864 | static int nfs4_init_client(struct nfs_client *clp, | ||
| 865 | int proto, int timeo, int retrans, | ||
| 866 | rpc_authflavor_t authflavour) | ||
| 867 | { | ||
| 868 | int error; | ||
| 869 | |||
| 870 | if (clp->cl_cons_state == NFS_CS_READY) { | ||
| 871 | /* the client is initialised already */ | ||
| 872 | dprintk("<-- nfs4_init_client() = 0 [already %p]\n", clp); | ||
| 873 | return 0; | ||
| 874 | } | ||
| 875 | |||
| 876 | /* Check NFS protocol revision and initialize RPC op vector */ | ||
| 877 | clp->rpc_ops = &nfs_v4_clientops; | ||
| 878 | |||
| 879 | error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour); | ||
| 880 | if (error < 0) | ||
| 881 | goto error; | ||
| 882 | |||
| 883 | error = nfs_idmap_new(clp); | ||
| 884 | if (error < 0) { | ||
| 885 | dprintk("%s: failed to create idmapper. Error = %d\n", | ||
| 886 | __FUNCTION__, error); | ||
| 887 | goto error; | ||
| 888 | } | ||
| 889 | __set_bit(NFS_CS_IDMAP, &clp->cl_res_state); | ||
| 890 | |||
| 891 | nfs_mark_client_ready(clp, NFS_CS_READY); | ||
| 892 | return 0; | ||
| 893 | |||
| 894 | error: | ||
| 895 | nfs_mark_client_ready(clp, error); | ||
| 896 | dprintk("<-- nfs4_init_client() = xerror %d\n", error); | ||
| 897 | return error; | ||
| 898 | } | ||
| 899 | |||
| 900 | /* | ||
| 901 | * Set up an NFS4 client | ||
| 902 | */ | ||
| 903 | static int nfs4_set_client(struct nfs_server *server, | ||
| 904 | const char *hostname, const struct sockaddr_in *addr, | ||
| 905 | rpc_authflavor_t authflavour, | ||
| 906 | int proto, int timeo, int retrans) | ||
| 907 | { | ||
| 908 | struct nfs_client *clp; | ||
| 909 | int error; | ||
| 910 | |||
| 911 | dprintk("--> nfs4_set_client()\n"); | ||
| 912 | |||
| 913 | /* Allocate or find a client reference we can use */ | ||
| 914 | clp = nfs_get_client(hostname, addr, 4); | ||
| 915 | if (IS_ERR(clp)) { | ||
| 916 | error = PTR_ERR(clp); | ||
| 917 | goto error; | ||
| 918 | } | ||
| 919 | error = nfs4_init_client(clp, proto, timeo, retrans, authflavour); | ||
| 920 | if (error < 0) | ||
| 921 | goto error_put; | ||
| 922 | |||
| 923 | server->nfs_client = clp; | ||
| 924 | dprintk("<-- nfs4_set_client() = 0 [new %p]\n", clp); | ||
| 925 | return 0; | ||
| 926 | |||
| 927 | error_put: | ||
| 928 | nfs_put_client(clp); | ||
| 929 | error: | ||
| 930 | dprintk("<-- nfs4_set_client() = xerror %d\n", error); | ||
| 931 | return error; | ||
| 932 | } | ||
| 933 | |||
| 934 | /* | ||
| 935 | * Create a version 4 volume record | ||
| 936 | */ | ||
| 937 | static int nfs4_init_server(struct nfs_server *server, | ||
| 938 | const struct nfs4_mount_data *data, rpc_authflavor_t authflavour) | ||
| 939 | { | ||
| 940 | int error; | ||
| 941 | |||
| 942 | dprintk("--> nfs4_init_server()\n"); | ||
| 943 | |||
| 944 | /* Initialise the client representation from the mount data */ | ||
| 945 | server->flags = data->flags & NFS_MOUNT_FLAGMASK; | ||
| 946 | server->caps |= NFS_CAP_ATOMIC_OPEN; | ||
| 947 | |||
| 948 | if (data->rsize) | ||
| 949 | server->rsize = nfs_block_size(data->rsize, NULL); | ||
| 950 | if (data->wsize) | ||
| 951 | server->wsize = nfs_block_size(data->wsize, NULL); | ||
| 952 | |||
| 953 | server->acregmin = data->acregmin * HZ; | ||
| 954 | server->acregmax = data->acregmax * HZ; | ||
| 955 | server->acdirmin = data->acdirmin * HZ; | ||
| 956 | server->acdirmax = data->acdirmax * HZ; | ||
| 957 | |||
| 958 | error = nfs_init_server_rpcclient(server, authflavour); | ||
| 959 | |||
| 960 | /* Done */ | ||
| 961 | dprintk("<-- nfs4_init_server() = %d\n", error); | ||
| 962 | return error; | ||
| 963 | } | ||
| 964 | |||
| 965 | /* | ||
| 966 | * Create a version 4 volume record | ||
| 967 | * - keyed on server and FSID | ||
| 968 | */ | ||
| 969 | struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data, | ||
| 970 | const char *hostname, | ||
| 971 | const struct sockaddr_in *addr, | ||
| 972 | const char *mntpath, | ||
| 973 | const char *ip_addr, | ||
| 974 | rpc_authflavor_t authflavour, | ||
| 975 | struct nfs_fh *mntfh) | ||
| 976 | { | ||
| 977 | struct nfs_fattr fattr; | ||
| 978 | struct nfs_server *server; | ||
| 979 | int error; | ||
| 980 | |||
| 981 | dprintk("--> nfs4_create_server()\n"); | ||
| 982 | |||
| 983 | server = nfs_alloc_server(); | ||
| 984 | if (!server) | ||
| 985 | return ERR_PTR(-ENOMEM); | ||
| 986 | |||
| 987 | /* Get a client record */ | ||
| 988 | error = nfs4_set_client(server, hostname, addr, authflavour, | ||
| 989 | data->proto, data->timeo, data->retrans); | ||
| 990 | if (error < 0) | ||
| 991 | goto error; | ||
| 992 | |||
| 993 | /* set up the general RPC client */ | ||
| 994 | error = nfs4_init_server(server, data, authflavour); | ||
| 995 | if (error < 0) | ||
| 996 | goto error; | ||
| 997 | |||
| 998 | BUG_ON(!server->nfs_client); | ||
| 999 | BUG_ON(!server->nfs_client->rpc_ops); | ||
| 1000 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); | ||
| 1001 | |||
| 1002 | /* Probe the root fh to retrieve its FSID */ | ||
| 1003 | error = nfs4_path_walk(server, mntfh, mntpath); | ||
| 1004 | if (error < 0) | ||
| 1005 | goto error; | ||
| 1006 | |||
| 1007 | dprintk("Server FSID: %llx:%llx\n", | ||
| 1008 | (unsigned long long) server->fsid.major, | ||
| 1009 | (unsigned long long) server->fsid.minor); | ||
| 1010 | dprintk("Mount FH: %d\n", mntfh->size); | ||
| 1011 | |||
| 1012 | error = nfs_probe_fsinfo(server, mntfh, &fattr); | ||
| 1013 | if (error < 0) | ||
| 1014 | goto error; | ||
| 1015 | |||
| 1016 | BUG_ON(!server->nfs_client); | ||
| 1017 | BUG_ON(!server->nfs_client->rpc_ops); | ||
| 1018 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); | ||
| 1019 | |||
| 1020 | spin_lock(&nfs_client_lock); | ||
| 1021 | list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); | ||
| 1022 | list_add_tail(&server->master_link, &nfs_volume_list); | ||
| 1023 | spin_unlock(&nfs_client_lock); | ||
| 1024 | |||
| 1025 | server->mount_time = jiffies; | ||
| 1026 | dprintk("<-- nfs4_create_server() = %p\n", server); | ||
| 1027 | return server; | ||
| 1028 | |||
| 1029 | error: | ||
| 1030 | nfs_free_server(server); | ||
| 1031 | dprintk("<-- nfs4_create_server() = error %d\n", error); | ||
| 1032 | return ERR_PTR(error); | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | /* | ||
| 1036 | * Create an NFS4 referral server record | ||
| 1037 | */ | ||
| 1038 | struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, | ||
| 1039 | struct nfs_fh *fh) | ||
| 1040 | { | ||
| 1041 | struct nfs_client *parent_client; | ||
| 1042 | struct nfs_server *server, *parent_server; | ||
| 1043 | struct nfs_fattr fattr; | ||
| 1044 | int error; | ||
| 1045 | |||
| 1046 | dprintk("--> nfs4_create_referral_server()\n"); | ||
| 1047 | |||
| 1048 | server = nfs_alloc_server(); | ||
| 1049 | if (!server) | ||
| 1050 | return ERR_PTR(-ENOMEM); | ||
| 1051 | |||
| 1052 | parent_server = NFS_SB(data->sb); | ||
| 1053 | parent_client = parent_server->nfs_client; | ||
| 1054 | |||
| 1055 | /* Get a client representation. | ||
| 1056 | * Note: NFSv4 always uses TCP, */ | ||
| 1057 | error = nfs4_set_client(server, data->hostname, data->addr, | ||
| 1058 | data->authflavor, | ||
| 1059 | parent_server->client->cl_xprt->prot, | ||
| 1060 | parent_client->retrans_timeo, | ||
| 1061 | parent_client->retrans_count); | ||
| 1062 | if (error < 0) | ||
| 1063 | goto error; | ||
| 1064 | |||
| 1065 | /* Initialise the client representation from the parent server */ | ||
| 1066 | nfs_server_copy_userdata(server, parent_server); | ||
| 1067 | server->caps |= NFS_CAP_ATOMIC_OPEN; | ||
| 1068 | |||
| 1069 | error = nfs_init_server_rpcclient(server, data->authflavor); | ||
| 1070 | if (error < 0) | ||
| 1071 | goto error; | ||
| 1072 | |||
| 1073 | BUG_ON(!server->nfs_client); | ||
| 1074 | BUG_ON(!server->nfs_client->rpc_ops); | ||
| 1075 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); | ||
| 1076 | |||
| 1077 | /* probe the filesystem info for this server filesystem */ | ||
| 1078 | error = nfs_probe_fsinfo(server, fh, &fattr); | ||
| 1079 | if (error < 0) | ||
| 1080 | goto error; | ||
| 1081 | |||
| 1082 | dprintk("Referral FSID: %llx:%llx\n", | ||
| 1083 | (unsigned long long) server->fsid.major, | ||
| 1084 | (unsigned long long) server->fsid.minor); | ||
| 1085 | |||
| 1086 | spin_lock(&nfs_client_lock); | ||
| 1087 | list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); | ||
| 1088 | list_add_tail(&server->master_link, &nfs_volume_list); | ||
| 1089 | spin_unlock(&nfs_client_lock); | ||
| 1090 | |||
| 1091 | server->mount_time = jiffies; | ||
| 1092 | |||
| 1093 | dprintk("<-- nfs_create_referral_server() = %p\n", server); | ||
| 1094 | return server; | ||
| 1095 | |||
| 1096 | error: | ||
| 1097 | nfs_free_server(server); | ||
| 1098 | dprintk("<-- nfs4_create_referral_server() = error %d\n", error); | ||
| 1099 | return ERR_PTR(error); | ||
| 1100 | } | ||
| 1101 | |||
| 1102 | #endif /* CONFIG_NFS_V4 */ | ||
| 1103 | |||
| 1104 | /* | ||
| 1105 | * Clone an NFS2, NFS3 or NFS4 server record | ||
| 1106 | */ | ||
| 1107 | struct nfs_server *nfs_clone_server(struct nfs_server *source, | ||
| 1108 | struct nfs_fh *fh, | ||
| 1109 | struct nfs_fattr *fattr) | ||
| 1110 | { | ||
| 1111 | struct nfs_server *server; | ||
| 1112 | struct nfs_fattr fattr_fsinfo; | ||
| 1113 | int error; | ||
| 1114 | |||
| 1115 | dprintk("--> nfs_clone_server(,%llx:%llx,)\n", | ||
| 1116 | (unsigned long long) fattr->fsid.major, | ||
| 1117 | (unsigned long long) fattr->fsid.minor); | ||
| 1118 | |||
| 1119 | server = nfs_alloc_server(); | ||
| 1120 | if (!server) | ||
| 1121 | return ERR_PTR(-ENOMEM); | ||
| 1122 | |||
| 1123 | /* Copy data from the source */ | ||
| 1124 | server->nfs_client = source->nfs_client; | ||
| 1125 | atomic_inc(&server->nfs_client->cl_count); | ||
| 1126 | nfs_server_copy_userdata(server, source); | ||
| 1127 | |||
| 1128 | server->fsid = fattr->fsid; | ||
| 1129 | |||
| 1130 | error = nfs_init_server_rpcclient(server, source->client->cl_auth->au_flavor); | ||
| 1131 | if (error < 0) | ||
| 1132 | goto out_free_server; | ||
| 1133 | if (!IS_ERR(source->client_acl)) | ||
| 1134 | nfs_init_server_aclclient(server); | ||
| 1135 | |||
| 1136 | /* probe the filesystem info for this server filesystem */ | ||
| 1137 | error = nfs_probe_fsinfo(server, fh, &fattr_fsinfo); | ||
| 1138 | if (error < 0) | ||
| 1139 | goto out_free_server; | ||
| 1140 | |||
| 1141 | dprintk("Cloned FSID: %llx:%llx\n", | ||
| 1142 | (unsigned long long) server->fsid.major, | ||
| 1143 | (unsigned long long) server->fsid.minor); | ||
| 1144 | |||
| 1145 | error = nfs_start_lockd(server); | ||
| 1146 | if (error < 0) | ||
| 1147 | goto out_free_server; | ||
| 1148 | |||
| 1149 | spin_lock(&nfs_client_lock); | ||
| 1150 | list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); | ||
| 1151 | list_add_tail(&server->master_link, &nfs_volume_list); | ||
| 1152 | spin_unlock(&nfs_client_lock); | ||
| 1153 | |||
| 1154 | server->mount_time = jiffies; | ||
| 1155 | |||
| 1156 | dprintk("<-- nfs_clone_server() = %p\n", server); | ||
| 1157 | return server; | ||
| 1158 | |||
| 1159 | out_free_server: | ||
| 1160 | nfs_free_server(server); | ||
| 1161 | dprintk("<-- nfs_clone_server() = error %d\n", error); | ||
| 1162 | return ERR_PTR(error); | ||
| 1163 | } | ||
| 1164 | |||
| 1165 | #ifdef CONFIG_PROC_FS | ||
| 1166 | static struct proc_dir_entry *proc_fs_nfs; | ||
| 1167 | |||
| 1168 | static int nfs_server_list_open(struct inode *inode, struct file *file); | ||
| 1169 | static void *nfs_server_list_start(struct seq_file *p, loff_t *pos); | ||
| 1170 | static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos); | ||
| 1171 | static void nfs_server_list_stop(struct seq_file *p, void *v); | ||
| 1172 | static int nfs_server_list_show(struct seq_file *m, void *v); | ||
| 1173 | |||
| 1174 | static struct seq_operations nfs_server_list_ops = { | ||
| 1175 | .start = nfs_server_list_start, | ||
| 1176 | .next = nfs_server_list_next, | ||
| 1177 | .stop = nfs_server_list_stop, | ||
| 1178 | .show = nfs_server_list_show, | ||
| 1179 | }; | ||
| 1180 | |||
| 1181 | static struct file_operations nfs_server_list_fops = { | ||
| 1182 | .open = nfs_server_list_open, | ||
| 1183 | .read = seq_read, | ||
| 1184 | .llseek = seq_lseek, | ||
| 1185 | .release = seq_release, | ||
| 1186 | }; | ||
| 1187 | |||
| 1188 | static int nfs_volume_list_open(struct inode *inode, struct file *file); | ||
| 1189 | static void *nfs_volume_list_start(struct seq_file *p, loff_t *pos); | ||
| 1190 | static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos); | ||
| 1191 | static void nfs_volume_list_stop(struct seq_file *p, void *v); | ||
| 1192 | static int nfs_volume_list_show(struct seq_file *m, void *v); | ||
| 1193 | |||
| 1194 | static struct seq_operations nfs_volume_list_ops = { | ||
| 1195 | .start = nfs_volume_list_start, | ||
| 1196 | .next = nfs_volume_list_next, | ||
| 1197 | .stop = nfs_volume_list_stop, | ||
| 1198 | .show = nfs_volume_list_show, | ||
| 1199 | }; | ||
| 1200 | |||
| 1201 | static struct file_operations nfs_volume_list_fops = { | ||
| 1202 | .open = nfs_volume_list_open, | ||
| 1203 | .read = seq_read, | ||
| 1204 | .llseek = seq_lseek, | ||
| 1205 | .release = seq_release, | ||
| 1206 | }; | ||
| 1207 | |||
| 1208 | /* | ||
| 1209 | * open "/proc/fs/nfsfs/servers" which provides a summary of servers with which | ||
| 1210 | * we're dealing | ||
| 1211 | */ | ||
| 1212 | static int nfs_server_list_open(struct inode *inode, struct file *file) | ||
| 1213 | { | ||
| 1214 | struct seq_file *m; | ||
| 1215 | int ret; | ||
| 1216 | |||
| 1217 | ret = seq_open(file, &nfs_server_list_ops); | ||
| 1218 | if (ret < 0) | ||
| 1219 | return ret; | ||
| 1220 | |||
| 1221 | m = file->private_data; | ||
| 1222 | m->private = PDE(inode)->data; | ||
| 1223 | |||
| 1224 | return 0; | ||
| 1225 | } | ||
| 1226 | |||
| 1227 | /* | ||
| 1228 | * set up the iterator to start reading from the server list and return the first item | ||
| 1229 | */ | ||
| 1230 | static void *nfs_server_list_start(struct seq_file *m, loff_t *_pos) | ||
| 1231 | { | ||
| 1232 | struct list_head *_p; | ||
| 1233 | loff_t pos = *_pos; | ||
| 1234 | |||
| 1235 | /* lock the list against modification */ | ||
| 1236 | spin_lock(&nfs_client_lock); | ||
| 1237 | |||
| 1238 | /* allow for the header line */ | ||
| 1239 | if (!pos) | ||
| 1240 | return SEQ_START_TOKEN; | ||
| 1241 | pos--; | ||
| 1242 | |||
| 1243 | /* find the n'th element in the list */ | ||
| 1244 | list_for_each(_p, &nfs_client_list) | ||
| 1245 | if (!pos--) | ||
| 1246 | break; | ||
| 1247 | |||
| 1248 | return _p != &nfs_client_list ? _p : NULL; | ||
| 1249 | } | ||
| 1250 | |||
| 1251 | /* | ||
| 1252 | * move to next server | ||
| 1253 | */ | ||
| 1254 | static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos) | ||
| 1255 | { | ||
| 1256 | struct list_head *_p; | ||
| 1257 | |||
| 1258 | (*pos)++; | ||
| 1259 | |||
| 1260 | _p = v; | ||
| 1261 | _p = (v == SEQ_START_TOKEN) ? nfs_client_list.next : _p->next; | ||
| 1262 | |||
| 1263 | return _p != &nfs_client_list ? _p : NULL; | ||
| 1264 | } | ||
| 1265 | |||
| 1266 | /* | ||
| 1267 | * clean up after reading from the transports list | ||
| 1268 | */ | ||
| 1269 | static void nfs_server_list_stop(struct seq_file *p, void *v) | ||
| 1270 | { | ||
| 1271 | spin_unlock(&nfs_client_lock); | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | /* | ||
| 1275 | * display a header line followed by a load of call lines | ||
| 1276 | */ | ||
| 1277 | static int nfs_server_list_show(struct seq_file *m, void *v) | ||
| 1278 | { | ||
| 1279 | struct nfs_client *clp; | ||
| 1280 | |||
| 1281 | /* display header on line 1 */ | ||
| 1282 | if (v == SEQ_START_TOKEN) { | ||
| 1283 | seq_puts(m, "NV SERVER PORT USE HOSTNAME\n"); | ||
| 1284 | return 0; | ||
| 1285 | } | ||
| 1286 | |||
| 1287 | /* display one transport per line on subsequent lines */ | ||
| 1288 | clp = list_entry(v, struct nfs_client, cl_share_link); | ||
| 1289 | |||
| 1290 | seq_printf(m, "v%d %02x%02x%02x%02x %4hx %3d %s\n", | ||
| 1291 | clp->cl_nfsversion, | ||
| 1292 | NIPQUAD(clp->cl_addr.sin_addr), | ||
| 1293 | ntohs(clp->cl_addr.sin_port), | ||
| 1294 | atomic_read(&clp->cl_count), | ||
| 1295 | clp->cl_hostname); | ||
| 1296 | |||
| 1297 | return 0; | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | /* | ||
| 1301 | * open "/proc/fs/nfsfs/volumes" which provides a summary of extant volumes | ||
| 1302 | */ | ||
| 1303 | static int nfs_volume_list_open(struct inode *inode, struct file *file) | ||
| 1304 | { | ||
| 1305 | struct seq_file *m; | ||
| 1306 | int ret; | ||
| 1307 | |||
| 1308 | ret = seq_open(file, &nfs_volume_list_ops); | ||
| 1309 | if (ret < 0) | ||
| 1310 | return ret; | ||
| 1311 | |||
| 1312 | m = file->private_data; | ||
| 1313 | m->private = PDE(inode)->data; | ||
| 1314 | |||
| 1315 | return 0; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | /* | ||
| 1319 | * set up the iterator to start reading from the volume list and return the first item | ||
| 1320 | */ | ||
| 1321 | static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos) | ||
| 1322 | { | ||
| 1323 | struct list_head *_p; | ||
| 1324 | loff_t pos = *_pos; | ||
| 1325 | |||
| 1326 | /* lock the list against modification */ | ||
| 1327 | spin_lock(&nfs_client_lock); | ||
| 1328 | |||
| 1329 | /* allow for the header line */ | ||
| 1330 | if (!pos) | ||
| 1331 | return SEQ_START_TOKEN; | ||
| 1332 | pos--; | ||
| 1333 | |||
| 1334 | /* find the n'th element in the list */ | ||
| 1335 | list_for_each(_p, &nfs_volume_list) | ||
| 1336 | if (!pos--) | ||
| 1337 | break; | ||
| 1338 | |||
| 1339 | return _p != &nfs_volume_list ? _p : NULL; | ||
| 1340 | } | ||
| 1341 | |||
| 1342 | /* | ||
| 1343 | * move to next volume | ||
| 1344 | */ | ||
| 1345 | static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos) | ||
| 1346 | { | ||
| 1347 | struct list_head *_p; | ||
| 1348 | |||
| 1349 | (*pos)++; | ||
| 1350 | |||
| 1351 | _p = v; | ||
| 1352 | _p = (v == SEQ_START_TOKEN) ? nfs_volume_list.next : _p->next; | ||
| 1353 | |||
| 1354 | return _p != &nfs_volume_list ? _p : NULL; | ||
| 1355 | } | ||
| 1356 | |||
| 1357 | /* | ||
| 1358 | * clean up after reading from the transports list | ||
| 1359 | */ | ||
| 1360 | static void nfs_volume_list_stop(struct seq_file *p, void *v) | ||
| 1361 | { | ||
| 1362 | spin_unlock(&nfs_client_lock); | ||
| 1363 | } | ||
| 1364 | |||
| 1365 | /* | ||
| 1366 | * display a header line followed by a load of call lines | ||
| 1367 | */ | ||
| 1368 | static int nfs_volume_list_show(struct seq_file *m, void *v) | ||
| 1369 | { | ||
| 1370 | struct nfs_server *server; | ||
| 1371 | struct nfs_client *clp; | ||
| 1372 | char dev[8], fsid[17]; | ||
| 1373 | |||
| 1374 | /* display header on line 1 */ | ||
| 1375 | if (v == SEQ_START_TOKEN) { | ||
| 1376 | seq_puts(m, "NV SERVER PORT DEV FSID\n"); | ||
| 1377 | return 0; | ||
| 1378 | } | ||
| 1379 | /* display one transport per line on subsequent lines */ | ||
| 1380 | server = list_entry(v, struct nfs_server, master_link); | ||
| 1381 | clp = server->nfs_client; | ||
| 1382 | |||
| 1383 | snprintf(dev, 8, "%u:%u", | ||
| 1384 | MAJOR(server->s_dev), MINOR(server->s_dev)); | ||
| 1385 | |||
| 1386 | snprintf(fsid, 17, "%llx:%llx", | ||
| 1387 | (unsigned long long) server->fsid.major, | ||
| 1388 | (unsigned long long) server->fsid.minor); | ||
| 1389 | |||
| 1390 | seq_printf(m, "v%d %02x%02x%02x%02x %4hx %-7s %-17s\n", | ||
| 1391 | clp->cl_nfsversion, | ||
| 1392 | NIPQUAD(clp->cl_addr.sin_addr), | ||
| 1393 | ntohs(clp->cl_addr.sin_port), | ||
| 1394 | dev, | ||
| 1395 | fsid); | ||
| 1396 | |||
| 1397 | return 0; | ||
| 1398 | } | ||
| 1399 | |||
| 1400 | /* | ||
| 1401 | * initialise the /proc/fs/nfsfs/ directory | ||
| 1402 | */ | ||
| 1403 | int __init nfs_fs_proc_init(void) | ||
| 1404 | { | ||
| 1405 | struct proc_dir_entry *p; | ||
| 1406 | |||
| 1407 | proc_fs_nfs = proc_mkdir("nfsfs", proc_root_fs); | ||
| 1408 | if (!proc_fs_nfs) | ||
| 1409 | goto error_0; | ||
| 1410 | |||
| 1411 | proc_fs_nfs->owner = THIS_MODULE; | ||
| 1412 | |||
| 1413 | /* a file of servers with which we're dealing */ | ||
| 1414 | p = create_proc_entry("servers", S_IFREG|S_IRUGO, proc_fs_nfs); | ||
| 1415 | if (!p) | ||
| 1416 | goto error_1; | ||
| 1417 | |||
| 1418 | p->proc_fops = &nfs_server_list_fops; | ||
| 1419 | p->owner = THIS_MODULE; | ||
| 1420 | |||
| 1421 | /* a file of volumes that we have mounted */ | ||
| 1422 | p = create_proc_entry("volumes", S_IFREG|S_IRUGO, proc_fs_nfs); | ||
| 1423 | if (!p) | ||
| 1424 | goto error_2; | ||
| 1425 | |||
| 1426 | p->proc_fops = &nfs_volume_list_fops; | ||
| 1427 | p->owner = THIS_MODULE; | ||
| 1428 | return 0; | ||
| 1429 | |||
| 1430 | error_2: | ||
| 1431 | remove_proc_entry("servers", proc_fs_nfs); | ||
| 1432 | error_1: | ||
| 1433 | remove_proc_entry("nfsfs", proc_root_fs); | ||
| 1434 | error_0: | ||
| 1435 | return -ENOMEM; | ||
| 1436 | } | ||
| 1437 | |||
| 1438 | /* | ||
| 1439 | * clean up the /proc/fs/nfsfs/ directory | ||
| 1440 | */ | ||
| 1441 | void nfs_fs_proc_exit(void) | ||
| 1442 | { | ||
| 1443 | remove_proc_entry("volumes", proc_fs_nfs); | ||
| 1444 | remove_proc_entry("servers", proc_fs_nfs); | ||
| 1445 | remove_proc_entry("nfsfs", proc_root_fs); | ||
| 1446 | } | ||
| 1447 | |||
| 1448 | #endif /* CONFIG_PROC_FS */ | ||
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #include "nfs4_fs.h" | 19 | #include "nfs4_fs.h" |
| 20 | #include "delegation.h" | 20 | #include "delegation.h" |
| 21 | #include "internal.h" | ||
| 21 | 22 | ||
| 22 | static struct nfs_delegation *nfs_alloc_delegation(void) | 23 | static struct nfs_delegation *nfs_alloc_delegation(void) |
| 23 | { | 24 | { |
| @@ -52,7 +53,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_ · 28 unmodified lines | |||
| 52 | case -NFS4ERR_EXPIRED: | 53 | case -NFS4ERR_EXPIRED: |
| 53 | /* kill_proc(fl->fl_pid, SIGLOST, 1); */ | 54 | /* kill_proc(fl->fl_pid, SIGLOST, 1); */ |
| 54 | case -NFS4ERR_STALE_CLIENTID: | 55 | case -NFS4ERR_STALE_CLIENTID: |
| 55 | nfs4_schedule_state_recovery(NFS_SERVER(inode)->nfs4_state); | 56 | nfs4_schedule_state_recovery(NFS_SERVER(inode)->nfs_client); |
| 56 | goto out_err; | 57 | goto out_err; |
| 57 | } | 58 | } |
| 58 | } | 59 | } |
| @@ -114,7 +115,7 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, st · 55 unmodified lines | |||
| 114 | */ | 115 | */ |
| 115 | int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res) | 116 | int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res) |
| 116 | { | 117 | { |
| 117 | struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state; | 118 | struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; |
| 118 | struct nfs_inode *nfsi = NFS_I(inode); | 119 | struct nfs_inode *nfsi = NFS_I(inode); |
| 119 | struct nfs_delegation *delegation; | 120 | struct nfs_delegation *delegation; |
| 120 | int status = 0; | 121 | int status = 0; |
| @@ -145,7 +146,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct · 24 unmodified lines | |||
| 145 | sizeof(delegation->stateid)) != 0 || | 146 | sizeof(delegation->stateid)) != 0 || |
| 146 | delegation->type != nfsi->delegation->type) { | 147 | delegation->type != nfsi->delegation->type) { |
| 147 | printk("%s: server %u.%u.%u.%u, handed out a duplicate delegation!\n", | 148 | printk("%s: server %u.%u.%u.%u, handed out a duplicate delegation!\n", |
| 148 | __FUNCTION__, NIPQUAD(clp->cl_addr)); | 149 | __FUNCTION__, NIPQUAD(clp->cl_addr.sin_addr)); |
| 149 | status = -EIO; | 150 | status = -EIO; |
| 150 | } | 151 | } |
| 151 | } | 152 | } |
| @@ -176,7 +177,7 @@ static void nfs_msync_inode(struct inode *inode) · 24 unmodified lines | |||
| 176 | */ | 177 | */ |
| 177 | int __nfs_inode_return_delegation(struct inode *inode) | 178 | int __nfs_inode_return_delegation(struct inode *inode) |
| 178 | { | 179 | { |
| 179 | struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state; | 180 | struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; |
| 180 | struct nfs_inode *nfsi = NFS_I(inode); | 181 | struct nfs_inode *nfsi = NFS_I(inode); |
| 181 | struct nfs_delegation *delegation; | 182 | struct nfs_delegation *delegation; |
| 182 | int res = 0; | 183 | int res = 0; |
| @@ -208,7 +209,7 @@ int __nfs_inode_return_delegation(struct inode *inode) · 25 unmodified lines | |||
| 208 | */ | 209 | */ |
| 209 | void nfs_return_all_delegations(struct super_block *sb) | 210 | void nfs_return_all_delegations(struct super_block *sb) |
| 210 | { | 211 | { |
| 211 | struct nfs4_client *clp = NFS_SB(sb)->nfs4_state; | 212 | struct nfs_client *clp = NFS_SB(sb)->nfs_client; |
| 212 | struct nfs_delegation *delegation; | 213 | struct nfs_delegation *delegation; |
| 213 | struct inode *inode; | 214 | struct inode *inode; |
| 214 | 215 | ||
| @@ -232,7 +233,7 @@ restart: · 17 unmodified lines | |||
| 232 | 233 | ||
| 233 | int nfs_do_expire_all_delegations(void *ptr) | 234 | int nfs_do_expire_all_delegations(void *ptr) |
| 234 | { | 235 | { |
| 235 | struct nfs4_client *clp = ptr; | 236 | struct nfs_client *clp = ptr; |
| 236 | struct nfs_delegation *delegation; | 237 | struct nfs_delegation *delegation; |
| 237 | struct inode *inode; | 238 | struct inode *inode; |
| 238 | 239 | ||
| @@ -254,11 +255,11 @@ restart: · 15 unmodified lines | |||
| 254 | } | 255 | } |
| 255 | out: | 256 | out: |
| 256 | spin_unlock(&clp->cl_lock); | 257 | spin_unlock(&clp->cl_lock); |
| 257 | nfs4_put_client(clp); | 258 | nfs_put_client(clp); |
| 258 | module_put_and_exit(0); | 259 | module_put_and_exit(0); |
| 259 | } | 260 | } |
| 260 | 261 | ||
| 261 | void nfs_expire_all_delegations(struct nfs4_client *clp) | 262 | void nfs_expire_all_delegations(struct nfs_client *clp) |
| 262 | { | 263 | { |
| 263 | struct task_struct *task; | 264 | struct task_struct *task; |
| 264 | 265 | ||
| @@ -266,17 +267,17 @@ void nfs_expire_all_delegations(struct nfs4_client *clp) · 1 unmodified line | |||
| 266 | atomic_inc(&clp->cl_count); | 267 | atomic_inc(&clp->cl_count); |
| 267 | task = kthread_run(nfs_do_expire_all_delegations, clp, | 268 | task = kthread_run(nfs_do_expire_all_delegations, clp, |
| 268 | "%u.%u.%u.%u-delegreturn", | 269 | "%u.%u.%u.%u-delegreturn", |
| 269 | NIPQUAD(clp->cl_addr)); | 270 | NIPQUAD(clp->cl_addr.sin_addr)); |
| 270 | if (!IS_ERR(task)) | 271 | if (!IS_ERR(task)) |
| 271 | return; | 272 | return; |
| 272 | nfs4_put_client(clp); | 273 | nfs_put_client(clp); |
| 273 | module_put(THIS_MODULE); | 274 | module_put(THIS_MODULE); |
| 274 | } | 275 | } |
| 275 | 276 | ||
| 276 | /* | 277 | /* |
| 277 | * Return all delegations following an NFS4ERR_CB_PATH_DOWN error. | 278 | * Return all delegations following an NFS4ERR_CB_PATH_DOWN error. |
| 278 | */ | 279 | */ |
| 279 | void nfs_handle_cb_pathdown(struct nfs4_client *clp) | 280 | void nfs_handle_cb_pathdown(struct nfs_client *clp) |
| 280 | { | 281 | { |
| 281 | struct nfs_delegation *delegation; | 282 | struct nfs_delegation *delegation; |
| 282 | struct inode *inode; | 283 | struct inode *inode; |
| @@ -299,7 +300,7 @@ restart: · 16 unmodified lines | |||
| 299 | 300 | ||
| 300 | struct recall_threadargs { | 301 | struct recall_threadargs { |
| 301 | struct inode *inode; | 302 | struct inode *inode; |
| 302 | struct nfs4_client *clp; | 303 | struct nfs_client *clp; |
| 303 | const nfs4_stateid *stateid; | 304 | const nfs4_stateid *stateid; |
| 304 | 305 | ||
| 305 | struct completion started; | 306 | struct completion started; |
| @@ -310,7 +311,7 @@ static int recall_thread(void *data) · 4 unmodified lines | |||
| 310 | { | 311 | { |
| 311 | struct recall_threadargs *args = (struct recall_threadargs *)data; | 312 | struct recall_threadargs *args = (struct recall_threadargs *)data; |
| 312 | struct inode *inode = igrab(args->inode); | 313 | struct inode *inode = igrab(args->inode); |
| 313 | struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state; | 314 | struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; |
| 314 | struct nfs_inode *nfsi = NFS_I(inode); | 315 | struct nfs_inode *nfsi = NFS_I(inode); |
| 315 | struct nfs_delegation *delegation; | 316 | struct nfs_delegation *delegation; |
| 316 | 317 | ||
| @@ -371,7 +372,7 @@ out_module_put: · 54 unmodified lines | |||
| 371 | /* | 372 | /* |
| 372 | * Retrieve the inode associated with a delegation | 373 | * Retrieve the inode associated with a delegation |
| 373 | */ | 374 | */ |
| 374 | struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle) | 375 | struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle) |
| 375 | { | 376 | { |
| 376 | struct nfs_delegation *delegation; | 377 | struct nfs_delegation *delegation; |
| 377 | struct inode *res = NULL; | 378 | struct inode *res = NULL; |
| @@ -389,7 +390,7 @@ struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nf · 11 unmodified lines | |||
| 389 | /* | 390 | /* |
| 390 | * Mark all delegations as needing to be reclaimed | 391 | * Mark all delegations as needing to be reclaimed |
| 391 | */ | 392 | */ |
| 392 | void nfs_delegation_mark_reclaim(struct nfs4_client *clp) | 393 | void nfs_delegation_mark_reclaim(struct nfs_client *clp) |
| 393 | { | 394 | { |
| 394 | struct nfs_delegation *delegation; | 395 | struct nfs_delegation *delegation; |
| 395 | spin_lock(&clp->cl_lock); | 396 | spin_lock(&clp->cl_lock); |
| @@ -401,7 +402,7 @@ void nfs_delegation_mark_reclaim(struct nfs4_client *clp) · 5 unmodified lines | |||
| 401 | /* | 402 | /* |
| 402 | * Reap all unclaimed delegations after reboot recovery is done | 403 | * Reap all unclaimed delegations after reboot recovery is done |
| 403 | */ | 404 | */ |
| 404 | void nfs_delegation_reap_unclaimed(struct nfs4_client *clp) | 405 | void nfs_delegation_reap_unclaimed(struct nfs_client *clp) |
| 405 | { | 406 | { |
| 406 | struct nfs_delegation *delegation, *n; | 407 | struct nfs_delegation *delegation, *n; |
| 407 | LIST_HEAD(head); | 408 | LIST_HEAD(head); |
| @@ -423,7 +424,7 @@ void nfs_delegation_reap_unclaimed(struct nfs4_client *clp) · 15 unmodified lines | |||
| 423 | 424 | ||
| 424 | int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode) | 425 | int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode) |
| 425 | { | 426 | { |
| 426 | struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state; | 427 | struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; |
| 427 | struct nfs_inode *nfsi = NFS_I(inode); | 428 | struct nfs_inode *nfsi = NFS_I(inode); |
| 428 | struct nfs_delegation *delegation; | 429 | struct nfs_delegation *delegation; |
| 429 | int res = 0; | 430 | int res = 0; |
| @@ -29,13 +29,13 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, st · 28 unmodified lines | |||
| 29 | int __nfs_inode_return_delegation(struct inode *inode); | 29 | int __nfs_inode_return_delegation(struct inode *inode); |
| 30 | int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid); | 30 | int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid); |
| 31 | 31 | ||
| 32 | struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle); | 32 | struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle); |
| 33 | void nfs_return_all_delegations(struct super_block *sb); | 33 | void nfs_return_all_delegations(struct super_block *sb); |
| 34 | void nfs_expire_all_delegations(struct nfs4_client *clp); | 34 | void nfs_expire_all_delegations(struct nfs_client *clp); |
| 35 | void nfs_handle_cb_pathdown(struct nfs4_client *clp); | 35 | void nfs_handle_cb_pathdown(struct nfs_client *clp); |
| 36 | 36 | ||
| 37 | void nfs_delegation_mark_reclaim(struct nfs4_client *clp); | 37 | void nfs_delegation_mark_reclaim(struct nfs_client *clp); |
| 38 | void nfs_delegation_reap_unclaimed(struct nfs4_client *clp); | 38 | void nfs_delegation_reap_unclaimed(struct nfs_client *clp); |
| 39 | 39 | ||
| 40 | /* NFSv4 delegation-related procedures */ | 40 | /* NFSv4 delegation-related procedures */ |
| 41 | int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid); | 41 | int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid); |
| @@ -30,7 +30,9 @@ · 29 unmodified lines | |||
| 30 | #include <linux/nfs_mount.h> | 30 | #include <linux/nfs_mount.h> |
| 31 | #include <linux/pagemap.h> | 31 | #include <linux/pagemap.h> |
| 32 | #include <linux/smp_lock.h> | 32 | #include <linux/smp_lock.h> |
| 33 | #include <linux/pagevec.h> | ||
| 33 | #include <linux/namei.h> | 34 | #include <linux/namei.h> |
| 35 | #include <linux/mount.h> | ||
| 34 | 36 | ||
| 35 | #include "nfs4_fs.h" | 37 | #include "nfs4_fs.h" |
| 36 | #include "delegation.h" | 38 | #include "delegation.h" |
| @@ -870,14 +872,14 @@ int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) · 833 unmodified lines | |||
| 870 | return (nd->intent.open.flags & O_EXCL) != 0; | 872 | return (nd->intent.open.flags & O_EXCL) != 0; |
| 871 | } | 873 | } |
| 872 | 874 | ||
| 873 | static inline int nfs_reval_fsid(struct inode *dir, | 875 | static inline int nfs_reval_fsid(struct vfsmount *mnt, struct inode *dir, |
| 874 | struct nfs_fh *fh, struct nfs_fattr *fattr) | 876 | struct nfs_fh *fh, struct nfs_fattr *fattr) |
| 875 | { | 877 | { |
| 876 | struct nfs_server *server = NFS_SERVER(dir); | 878 | struct nfs_server *server = NFS_SERVER(dir); |
| 877 | 879 | ||
| 878 | if (!nfs_fsid_equal(&server->fsid, &fattr->fsid)) | 880 | if (!nfs_fsid_equal(&server->fsid, &fattr->fsid)) |
| 879 | /* Revalidate fsid on root dir */ | 881 | /* Revalidate fsid on root dir */ |
| 880 | return __nfs_revalidate_inode(server, dir->i_sb->s_root->d_inode); | 882 | return __nfs_revalidate_inode(server, mnt->mnt_root->d_inode); |
| 881 | return 0; | 883 | return 0; |
| 882 | } | 884 | } |
| 883 | 885 | ||
| @@ -902,9 +904,15 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru · 18 unmodified lines | |||
| 902 | 904 | ||
| 903 | lock_kernel(); | 905 | lock_kernel(); |
| 904 | 906 | ||
| 905 | /* If we're doing an exclusive create, optimize away the lookup */ | 907 | /* |
| 906 | if (nfs_is_exclusive_create(dir, nd)) | 908 | * If we're doing an exclusive create, optimize away the lookup |
| 907 | goto no_entry; | 909 | * but don't hash the dentry. |
| 910 | */ | ||
| 911 | if (nfs_is_exclusive_create(dir, nd)) { | ||
| 912 | d_instantiate(dentry, NULL); | ||
| 913 | res = NULL; | ||
| 914 | goto out_unlock; | ||
| 915 | } | ||
| 908 | 916 | ||
| 909 | error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); | 917 | error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); |
| 910 | if (error == -ENOENT) | 918 | if (error == -ENOENT) |
| @@ -913,7 +921,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru · 2 unmodified lines | |||
| 913 | res = ERR_PTR(error); | 921 | res = ERR_PTR(error); |
| 914 | goto out_unlock; | 922 | goto out_unlock; |
| 915 | } | 923 | } |
| 916 | error = nfs_reval_fsid(dir, &fhandle, &fattr); | 924 | error = nfs_reval_fsid(nd->mnt, dir, &fhandle, &fattr); |
| 917 | if (error < 0) { | 925 | if (error < 0) { |
| 918 | res = ERR_PTR(error); | 926 | res = ERR_PTR(error); |
| 919 | goto out_unlock; | 927 | goto out_unlock; |
| @@ -922,8 +930,9 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru · 2 unmodified lines | |||
| 922 | res = (struct dentry *)inode; | 930 | res = (struct dentry *)inode; |
| 923 | if (IS_ERR(res)) | 931 | if (IS_ERR(res)) |
| 924 | goto out_unlock; | 932 | goto out_unlock; |
| 933 | |||
| 925 | no_entry: | 934 | no_entry: |
| 926 | res = d_add_unique(dentry, inode); | 935 | res = d_materialise_unique(dentry, inode); |
| 927 | if (res != NULL) | 936 | if (res != NULL) |
| 928 | dentry = res; | 937 | dentry = res; |
| 929 | nfs_renew_times(dentry); | 938 | nfs_renew_times(dentry); |
| @@ -1117,11 +1126,13 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc) · 187 unmodified lines | |||
| 1117 | dput(dentry); | 1126 | dput(dentry); |
| 1118 | return NULL; | 1127 | return NULL; |
| 1119 | } | 1128 | } |
| 1120 | alias = d_add_unique(dentry, inode); | 1129 | |
| 1130 | alias = d_materialise_unique(dentry, inode); | ||
| 1121 | if (alias != NULL) { | 1131 | if (alias != NULL) { |
| 1122 | dput(dentry); | 1132 | dput(dentry); |
| 1123 | dentry = alias; | 1133 | dentry = alias; |
| 1124 | } | 1134 | } |
| 1135 | |||
| 1125 | nfs_renew_times(dentry); | 1136 | nfs_renew_times(dentry); |
| 1126 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 1137 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
| 1127 | return dentry; | 1138 | return dentry; |
| @@ -1143,23 +1154,22 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle, · 15 unmodified lines | |||
| 1143 | struct inode *dir = dentry->d_parent->d_inode; | 1154 | struct inode *dir = dentry->d_parent->d_inode; |
| 1144 | error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); | 1155 | error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); |
| 1145 | if (error) | 1156 | if (error) |
| 1146 | goto out_err; | 1157 | return error; |
| 1147 | } | 1158 | } |
| 1148 | if (!(fattr->valid & NFS_ATTR_FATTR)) { | 1159 | if (!(fattr->valid & NFS_ATTR_FATTR)) { |
| 1149 | struct nfs_server *server = NFS_SB(dentry->d_sb); | 1160 | struct nfs_server *server = NFS_SB(dentry->d_sb); |
| 1150 | error = server->rpc_ops->getattr(server, fhandle, fattr); | 1161 | error = server->nfs_client->rpc_ops->getattr(server, fhandle, fattr); |
| 1151 | if (error < 0) | 1162 | if (error < 0) |
| 1152 | goto out_err; | 1163 | return error; |
| 1153 | } | 1164 | } |
| 1154 | inode = nfs_fhget(dentry->d_sb, fhandle, fattr); | 1165 | inode = nfs_fhget(dentry->d_sb, fhandle, fattr); |
| 1155 | error = PTR_ERR(inode); | 1166 | error = PTR_ERR(inode); |
| 1156 | if (IS_ERR(inode)) | 1167 | if (IS_ERR(inode)) |
| 1157 | goto out_err; | 1168 | return error; |
| 1158 | d_instantiate(dentry, inode); | 1169 | d_instantiate(dentry, inode); |
| 1170 | if (d_unhashed(dentry)) | ||
| 1171 | d_rehash(dentry); | ||
| 1159 | return 0; | 1172 | return 0; |
| 1160 | out_err: | ||
| 1161 | d_drop(dentry); | ||
| 1162 | return error; | ||
| 1163 | } | 1173 | } |
| 1164 | 1174 | ||
| 1165 | /* | 1175 | /* |
| @@ -1440,48 +1450,82 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) · 274 unmodified lines | |||
| 1440 | return error; | 1450 | return error; |
| 1441 | } | 1451 | } |
| 1442 | 1452 | ||
| 1443 | static int | 1453 | /* |
| 1444 | nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | 1454 | * To create a symbolic link, most file systems instantiate a new inode, |
| 1455 | * add a page to it containing the path, then write it out to the disk | ||
| 1456 | * using prepare_write/commit_write. | ||
| 1457 | * | ||
| 1458 | * Unfortunately the NFS client can't create the in-core inode first | ||
| 1459 | * because it needs a file handle to create an in-core inode (see | ||
| 1460 | * fs/nfs/inode.c:nfs_fhget). We only have a file handle *after* the | ||
| 1461 | * symlink request has completed on the server. | ||
| 1462 | * | ||
| 1463 | * So instead we allocate a raw page, copy the symname into it, then do | ||
| 1464 | * the SYMLINK request with the page as the buffer. If it succeeds, we | ||
| 1465 | * now have a new file handle and can instantiate an in-core NFS inode | ||
| 1466 | * and move the raw page into its mapping. | ||
| 1467 | */ | ||
| 1468 | static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | ||
| 1445 | { | 1469 | { |
| 1470 | struct pagevec lru_pvec; | ||
| 1471 | struct page *page; | ||
| 1472 | char *kaddr; | ||
| 1446 | struct iattr attr; | 1473 | struct iattr attr; |
| 1447 | struct nfs_fattr sym_attr; | 1474 | unsigned int pathlen = strlen(symname); |
| 1448 | struct nfs_fh sym_fh; | ||
| 1449 | struct qstr qsymname; | ||
| 1450 | int error; | 1475 | int error; |
| 1451 | 1476 | ||
| 1452 | dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s)\n", dir->i_sb->s_id, | 1477 | dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s)\n", dir->i_sb->s_id, |
| 1453 | dir->i_ino, dentry->d_name.name, symname); | 1478 | dir->i_ino, dentry->d_name.name, symname); |
| 1454 | 1479 | ||
| 1455 | #ifdef NFS_PARANOIA | 1480 | if (pathlen > PAGE_SIZE) |
| 1456 | if (dentry->d_inode) | 1481 | return -ENAMETOOLONG; |
| 1457 | printk("nfs_proc_symlink: %s/%s not negative!\n", | ||
| 1458 | dentry->d_parent->d_name.name, dentry->d_name.name); | ||
| 1459 | #endif | ||
| 1460 | /* | ||
| 1461 | * Fill in the sattr for the call. | ||
| 1462 | * Note: SunOS 4.1.2 crashes if the mode isn't initialized! | ||
| 1463 | */ | ||
| 1464 | attr.ia_valid = ATTR_MODE; | ||
| 1465 | attr.ia_mode = S_IFLNK | S_IRWXUGO; | ||
| 1466 | 1482 | ||
| 1467 | qsymname.name = symname; | 1483 | attr.ia_mode = S_IFLNK | S_IRWXUGO; |
| 1468 | qsymname.len = strlen(symname); | 1484 | attr.ia_valid = ATTR_MODE; |
| 1469 | 1485 | ||
| 1470 | lock_kernel(); | 1486 | lock_kernel(); |
| 1487 | |||
| 1488 | page = alloc_page(GFP_KERNEL); | ||
| 1489 | if (!page) { | ||
| 1490 | unlock_kernel(); | ||
| 1491 | return -ENOMEM; | ||
| 1492 | } | ||
| 1493 | |||
| 1494 | kaddr = kmap_atomic(page, KM_USER0); | ||
| 1495 | memcpy(kaddr, symname, pathlen); | ||
| 1496 | if (pathlen < PAGE_SIZE) | ||
| 1497 | memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen); | ||
| 1498 | kunmap_atomic(kaddr, KM_USER0); | ||
| 1499 | |||
| 1471 | nfs_begin_data_update(dir); | 1500 | nfs_begin_data_update(dir); |
| 1472 | error = NFS_PROTO(dir)->symlink(dir, &dentry->d_name, &qsymname, | 1501 | error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr); |
| 1473 | &attr, &sym_fh, &sym_attr); | ||
| 1474 | nfs_end_data_update(dir); | 1502 | nfs_end_data_update(dir); |
| 1475 | if (!error) { | 1503 | if (error != 0) { |
| 1476 | error = nfs_instantiate(dentry, &sym_fh, &sym_attr); | 1504 | dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s) error %d\n", |
| 1477 | } else { | 1505 | dir->i_sb->s_id, dir->i_ino, |
| 1478 | if (error == -EEXIST) | 1506 | dentry->d_name.name, symname, error); |
| 1479 | printk("nfs_proc_symlink: %s/%s already exists??\n", | ||
| 1480 | dentry->d_parent->d_name.name, dentry->d_name.name); | ||
| 1481 | d_drop(dentry); | 1507 | d_drop(dentry); |
| 1508 | __free_page(page); | ||
| 1509 | unlock_kernel(); | ||
| 1510 | return error; | ||
| 1482 | } | 1511 | } |
| 1512 | |||
| 1513 | /* | ||
| 1514 | * No big deal if we can't add this page to the page cache here. | ||
| 1515 | * READLINK will get the missing page from the server if needed. | ||
| 1516 | */ | ||
| 1517 | pagevec_init(&lru_pvec, 0); | ||
| 1518 | if (!add_to_page_cache(page, dentry->d_inode->i_mapping, 0, | ||
| 1519 | GFP_KERNEL)) { | ||
| 1520 | if (!pagevec_add(&lru_pvec, page)) | ||
| 1521 | __pagevec_lru_add(&lru_pvec); | ||
| 1522 | SetPageUptodate(page); | ||
| 1523 | unlock_page(page); | ||
| 1524 | } else | ||
| 1525 | __free_page(page); | ||
| 1526 | |||
| 1483 | unlock_kernel(); | 1527 | unlock_kernel(); |
| 1484 | return error; | 1528 | return 0; |
| 1485 | } | 1529 | } |
| 1486 | 1530 | ||
| 1487 | static int | 1531 | static int |
| @@ -1638,35 +1682,211 @@ out: · 150 unmodified lines | |||
| 1638 | return error; | 1682 | return error; |
| 1639 | } | 1683 | } |
| 1640 | 1684 | ||
| 1685 | static DEFINE_SPINLOCK(nfs_access_lru_lock); | ||
| 1686 | static LIST_HEAD(nfs_access_lru_list); | ||
| 1687 | static atomic_long_t nfs_access_nr_entries; | ||
| 1688 | |||
| 1689 | static void nfs_access_free_entry(struct nfs_access_entry *entry) | ||
| 1690 | { | ||
| 1691 | put_rpccred(entry->cred); | ||
| 1692 | kfree(entry); | ||
| 1693 | smp_mb__before_atomic_dec(); | ||
| 1694 | atomic_long_dec(&nfs_access_nr_entries); | ||
| 1695 | smp_mb__after_atomic_dec(); | ||
| 1696 | } | ||
| 1697 | |||
| 1698 | int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask) | ||
| 1699 | { | ||
| 1700 | LIST_HEAD(head); | ||
| 1701 | struct nfs_inode *nfsi; | ||
| 1702 | struct nfs_access_entry *cache; | ||
| 1703 | |||
| 1704 | spin_lock(&nfs_access_lru_lock); | ||
| 1705 | restart: | ||
| 1706 | list_for_each_entry(nfsi, &nfs_access_lru_list, access_cache_inode_lru) { | ||
| 1707 | struct inode *inode; | ||
| 1708 | |||
| 1709 | if (nr_to_scan-- == 0) | ||
| 1710 | break; | ||
| 1711 | inode = igrab(&nfsi->vfs_inode); | ||
| 1712 | if (inode == NULL) | ||
| 1713 | continue; | ||
| 1714 | spin_lock(&inode->i_lock); | ||
| 1715 | if (list_empty(&nfsi->access_cache_entry_lru)) | ||
| 1716 | goto remove_lru_entry; | ||
| 1717 | cache = list_entry(nfsi->access_cache_entry_lru.next, | ||
| 1718 | struct nfs_access_entry, lru); | ||
| 1719 | list_move(&cache->lru, &head); | ||
| 1720 | rb_erase(&cache->rb_node, &nfsi->access_cache); | ||
| 1721 | if (!list_empty(&nfsi->access_cache_entry_lru)) | ||
| 1722 | list_move_tail(&nfsi->access_cache_inode_lru, | ||
| 1723 | &nfs_access_lru_list); | ||
| 1724 | else { | ||
| 1725 | remove_lru_entry: | ||
| 1726 | list_del_init(&nfsi->access_cache_inode_lru); | ||
| 1727 | clear_bit(NFS_INO_ACL_LRU_SET, &nfsi->flags); | ||
| 1728 | } | ||
| 1729 | spin_unlock(&inode->i_lock); | ||
| 1730 | iput(inode); | ||
| 1731 | goto restart; | ||
| 1732 | } | ||
| 1733 | spin_unlock(&nfs_access_lru_lock); | ||
| 1734 | while (!list_empty(&head)) { | ||
| 1735 | cache = list_entry(head.next, struct nfs_access_entry, lru); | ||
| 1736 | list_del(&cache->lru); | ||
| 1737 | nfs_access_free_entry(cache); | ||
| 1738 | } | ||
| 1739 | return (atomic_long_read(&nfs_access_nr_entries) / 100) * sysctl_vfs_cache_pressure; | ||
| 1740 | } | ||
| 1741 | |||
| 1742 | static void __nfs_access_zap_cache(struct inode *inode) | ||
| 1743 | { | ||
| 1744 | struct nfs_inode *nfsi = NFS_I(inode); | ||
| 1745 | struct rb_root *root_node = &nfsi->access_cache; | ||
| 1746 | struct rb_node *n, *dispose = NULL; | ||
| 1747 | struct nfs_access_entry *entry; | ||
| 1748 | |||
| 1749 | /* Unhook entries from the cache */ | ||
| 1750 | while ((n = rb_first(root_node)) != NULL) { | ||
| 1751 | entry = rb_entry(n, struct nfs_access_entry, rb_node); | ||
| 1752 | rb_erase(n, root_node); | ||
| 1753 | list_del(&entry->lru); | ||
| 1754 | n->rb_left = dispose; | ||
| 1755 | dispose = n; | ||
| 1756 | } | ||
| 1757 | nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS; | ||
| 1758 | spin_unlock(&inode->i_lock); | ||
| 1759 | |||
| 1760 | /* Now kill them all! */ | ||
| 1761 | while (dispose != NULL) { | ||
| 1762 | n = dispose; | ||
| 1763 | dispose = n->rb_left; | ||
| 1764 | nfs_access_free_entry(rb_entry(n, struct nfs_access_entry, rb_node)); | ||
| 1765 | } | ||
| 1766 | } | ||
| 1767 | |||
| 1768 | void nfs_access_zap_cache(struct inode *inode) | ||
| 1769 | { | ||
| 1770 | /* Remove from global LRU init */ | ||
| 1771 | if (test_and_clear_bit(NFS_INO_ACL_LRU_SET, &NFS_FLAGS(inode))) { | ||
| 1772 | spin_lock(&nfs_access_lru_lock); | ||
| 1773 | list_del_init(&NFS_I(inode)->access_cache_inode_lru); | ||
| 1774 | spin_unlock(&nfs_access_lru_lock); | ||
| 1775 | } | ||
| 1776 | |||
| 1777 | spin_lock(&inode->i_lock); | ||
| 1778 | /* This will release the spinlock */ | ||
| 1779 | __nfs_access_zap_cache(inode); | ||
| 1780 | } | ||
| 1781 | |||
| 1782 | static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred) | ||
| 1783 | { | ||
| 1784 | struct rb_node *n = NFS_I(inode)->access_cache.rb_node; | ||
| 1785 | struct nfs_access_entry *entry; | ||
| 1786 | |||
| 1787 | while (n != NULL) { | ||
| 1788 | entry = rb_entry(n, struct nfs_access_entry, rb_node); | ||
| 1789 | |||
| 1790 | if (cred < entry->cred) | ||
| 1791 | n = n->rb_left; | ||
| 1792 | else if (cred > entry->cred) | ||
| 1793 | n = n->rb_right; | ||
| 1794 | else | ||
| 1795 | return entry; | ||
| 1796 | } | ||
| 1797 | return NULL; | ||
| 1798 | } | ||
| 1799 | |||
| 1641 | int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res) | 1800 | int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res) |
| 1642 | { | 1801 | { |
| 1643 | struct nfs_inode *nfsi = NFS_I(inode); | 1802 | struct nfs_inode *nfsi = NFS_I(inode); |
| 1644 | struct nfs_access_entry *cache = &nfsi->cache_access; | 1803 | struct nfs_access_entry *cache; |
| 1804 | int err = -ENOENT; | ||
| 1645 | 1805 | ||
| 1646 | if (cache->cred != cred | 1806 | spin_lock(&inode->i_lock); |
| 1647 | || time_after(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode)) | 1807 | if (nfsi->cache_validity & NFS_INO_INVALID_ACCESS) |
| 1648 | || (nfsi->cache_validity & NFS_INO_INVALID_ACCESS)) | 1808 | goto out_zap; |
| 1649 | return -ENOENT; | 1809 | cache = nfs_access_search_rbtree(inode, cred); |
| 1650 | memcpy(res, cache, sizeof(*res)); | 1810 | if (cache == NULL) |
| 1651 | return 0; | 1811 | goto out; |
| 1812 | if (time_after(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode))) | ||
| 1813 | goto out_stale; | ||
| 1814 | res->jiffies = cache->jiffies; | ||
| 1815 | res->cred = cache->cred; | ||
| 1816 | res->mask = cache->mask; | ||
| 1817 | list_move_tail(&cache->lru, &nfsi->access_cache_entry_lru); | ||
| 1818 | err = 0; | ||
| 1819 | out: | ||
| 1820 | spin_unlock(&inode->i_lock); | ||
| 1821 | return err; | ||
| 1822 | out_stale: | ||
| 1823 | rb_erase(&cache->rb_node, &nfsi->access_cache); | ||
| 1824 | list_del(&cache->lru); | ||
| 1825 | spin_unlock(&inode->i_lock); | ||
| 1826 | nfs_access_free_entry(cache); | ||
| 1827 | return -ENOENT; | ||
| 1828 | out_zap: | ||
| 1829 | /* This will release the spinlock */ | ||
| 1830 | __nfs_access_zap_cache(inode); | ||
| 1831 | return -ENOENT; | ||
| 1652 | } | 1832 | } |
| 1653 | 1833 | ||
| 1654 | void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) | 1834 | static void nfs_access_add_rbtree(struct inode *inode, struct nfs_access_entry *set) |
| 1655 | { | 1835 | { |
| 1656 | struct nfs_inode *nfsi = NFS_I(inode); | 1836 | struct nfs_inode *nfsi = NFS_I(inode); |
| 1657 | struct nfs_access_entry *cache = &nfsi->cache_access; | 1837 | struct rb_root *root_node = &nfsi->access_cache; |
| 1838 | struct rb_node **p = &root_node->rb_node; | ||
| 1839 | struct rb_node *parent = NULL; | ||
| 1840 | struct nfs_access_entry *entry; | ||
| 1658 | 1841 | ||
| 1659 | if (cache->cred != set->cred) { | ||
| 1660 | if (cache->cred) | ||
| 1661 | put_rpccred(cache->cred); | ||
| 1662 | cache->cred = get_rpccred(set->cred); | ||
| 1663 | } | ||
| 1664 | /* FIXME: replace current access_cache BKL reliance with inode->i_lock */ | ||
| 1665 | spin_lock(&inode->i_lock); | 1842 | spin_lock(&inode->i_lock); |
| 1666 | nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS; | 1843 | while (*p != NULL) { |
| 1844 | parent = *p; | ||
| 1845 | entry = rb_entry(parent, struct nfs_access_entry, rb_node); | ||
| 1846 | |||
| 1847 | if (set->cred < entry->cred) | ||
| 1848 | p = &parent->rb_left; | ||
| 1849 | else if (set->cred > entry->cred) | ||
| 1850 | p = &parent->rb_right; | ||
| 1851 | else | ||
| 1852 | goto found; | ||
| 1853 | } | ||
| 1854 | rb_link_node(&set->rb_node, parent, p); | ||
| 1855 | rb_insert_color(&set->rb_node, root_node); | ||
| 1856 | list_add_tail(&set->lru, &nfsi->access_cache_entry_lru); | ||
| 1667 | spin_unlock(&inode->i_lock); | 1857 | spin_unlock(&inode->i_lock); |
| 1858 | return; | ||
| 1859 | found: | ||
| 1860 | rb_replace_node(parent, &set->rb_node, root_node); | ||
| 1861 | list_add_tail(&set->lru, &nfsi->access_cache_entry_lru); | ||
| 1862 | list_del(&entry->lru); | ||
| 1863 | spin_unlock(&inode->i_lock); | ||
| 1864 | nfs_access_free_entry(entry); | ||
| 1865 | } | ||
| 1866 | |||
| 1867 | void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) | ||
| 1868 | { | ||
| 1869 | struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL); | ||
| 1870 | if (cache == NULL) | ||
| 1871 | return; | ||
| 1872 | RB_CLEAR_NODE(&cache->rb_node); | ||
| 1668 | cache->jiffies = set->jiffies; | 1873 | cache->jiffies = set->jiffies; |
| 1874 | cache->cred = get_rpccred(set->cred); | ||
| 1669 | cache->mask = set->mask; | 1875 | cache->mask = set->mask; |
| 1876 | |||
| 1877 | nfs_access_add_rbtree(inode, cache); | ||
| 1878 | |||
| 1879 | /* Update accounting */ | ||
| 1880 | smp_mb__before_atomic_inc(); | ||
| 1881 | atomic_long_inc(&nfs_access_nr_entries); | ||
| 1882 | smp_mb__after_atomic_inc(); | ||
| 1883 | |||
| 1884 | /* Add inode to global LRU list */ | ||
| 1885 | if (!test_and_set_bit(NFS_INO_ACL_LRU_SET, &NFS_FLAGS(inode))) { | ||
| 1886 | spin_lock(&nfs_access_lru_lock); | ||
| 1887 | list_add_tail(&NFS_I(inode)->access_cache_inode_lru, &nfs_access_lru_list); | ||
| 1888 | spin_unlock(&nfs_access_lru_lock); | ||
| 1889 | } | ||
| 1670 | } | 1890 | } |
| 1671 | 1891 | ||
| 1672 | static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask) | 1892 | static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask) |
| @@ -111,7 +111,7 @@ nfs_file_open(struct inode *inode, struct file *filp) · 110 unmodified lines | |||
| 111 | 111 | ||
| 112 | nfs_inc_stats(inode, NFSIOS_VFSOPEN); | 112 | nfs_inc_stats(inode, NFSIOS_VFSOPEN); |
| 113 | lock_kernel(); | 113 | lock_kernel(); |
| 114 | res = NFS_SERVER(inode)->rpc_ops->file_open(inode, filp); | 114 | res = NFS_PROTO(inode)->file_open(inode, filp); |
| 115 | unlock_kernel(); | 115 | unlock_kernel(); |
| 116 | return res; | 116 | return res; |
| 117 | } | 117 | } |
| @@ -157,7 +157,7 @@ force_reval: · 39 unmodified lines | |||
| 157 | static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) | 157 | static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) |
| 158 | { | 158 | { |
| 159 | /* origin == SEEK_END => we must revalidate the cached file length */ | 159 | /* origin == SEEK_END => we must revalidate the cached file length */ |
| 160 | if (origin == 2) { | 160 | if (origin == SEEK_END) { |
| 161 | struct inode *inode = filp->f_mapping->host; | 161 | struct inode *inode = filp->f_mapping->host; |
| 162 | int retval = nfs_revalidate_file_size(inode, filp); | 162 | int retval = nfs_revalidate_file_size(inode, filp); |
| 163 | if (retval < 0) | 163 | if (retval < 0) |
| @@ -0,0 +1,311 @@ | |||
| 1 | /* getroot.c: get the root dentry for an NFS mount | ||
| 2 | * | ||
| 3 | * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. | ||
| 4 | * Written by David Howells (dhowells@redhat.com) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/config.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | |||
| 16 | #include <linux/time.h> | ||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/mm.h> | ||
| 19 | #include <linux/string.h> | ||
| 20 | #include <linux/stat.h> | ||
| 21 | #include <linux/errno.h> | ||
| 22 | #include <linux/unistd.h> | ||
| 23 | #include <linux/sunrpc/clnt.h> | ||
| 24 | #include <linux/sunrpc/stats.h> | ||
| 25 | #include <linux/nfs_fs.h> | ||
| 26 | #include <linux/nfs_mount.h> | ||
| 27 | #include <linux/nfs4_mount.h> | ||
| 28 | #include <linux/lockd/bind.h> | ||
| 29 | #include <linux/smp_lock.h> | ||
| 30 | #include <linux/seq_file.h> | ||
| 31 | #include <linux/mount.h> | ||
| 32 | #include <linux/nfs_idmap.h> | ||
| 33 | #include <linux/vfs.h> | ||
| 34 | #include <linux/namei.h> | ||
| 35 | #include <linux/namespace.h> | ||
| 36 | #include <linux/security.h> | ||
| 37 | |||
| 38 | #include <asm/system.h> | ||
| 39 | #include <asm/uaccess.h> | ||
| 40 | |||
| 41 | #include "nfs4_fs.h" | ||
| 42 | #include "delegation.h" | ||
| 43 | #include "internal.h" | ||
| 44 | |||
| 45 | #define NFSDBG_FACILITY NFSDBG_CLIENT | ||
| 46 | #define NFS_PARANOIA 1 | ||
| 47 | |||
| 48 | /* | ||
| 49 | * get an NFS2/NFS3 root dentry from the root filehandle | ||
| 50 | */ | ||
| 51 | struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh) | ||
| 52 | { | ||
| 53 | struct nfs_server *server = NFS_SB(sb); | ||
| 54 | struct nfs_fsinfo fsinfo; | ||
| 55 | struct nfs_fattr fattr; | ||
| 56 | struct dentry *mntroot; | ||
| 57 | struct inode *inode; | ||
| 58 | int error; | ||
| 59 | |||
| 60 | /* create a dummy root dentry with dummy inode for this superblock */ | ||
| 61 | if (!sb->s_root) { | ||
| 62 | struct nfs_fh dummyfh; | ||
| 63 | struct dentry *root; | ||
| 64 | struct inode *iroot; | ||
| 65 | |||
| 66 | memset(&dummyfh, 0, sizeof(dummyfh)); | ||
| 67 | memset(&fattr, 0, sizeof(fattr)); | ||
| 68 | nfs_fattr_init(&fattr); | ||
| 69 | fattr.valid = NFS_ATTR_FATTR; | ||
| 70 | fattr.type = NFDIR; | ||
| 71 | fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR; | ||
| 72 | fattr.nlink = 2; | ||
| 73 | |||
| 74 | iroot = nfs_fhget(sb, &dummyfh, &fattr); | ||
| 75 | if (IS_ERR(iroot)) | ||
| 76 | return ERR_PTR(PTR_ERR(iroot)); | ||
| 77 | |||
| 78 | root = d_alloc_root(iroot); | ||
| 79 | if (!root) { | ||
| 80 | iput(iroot); | ||
| 81 | return ERR_PTR(-ENOMEM); | ||
| 82 | } | ||
| 83 | |||
| 84 | sb->s_root = root; | ||
| 85 | } | ||
| 86 | |||
| 87 | /* get the actual root for this mount */ | ||
| 88 | fsinfo.fattr = &fattr; | ||
| 89 | |||
| 90 | error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo); | ||
| 91 | if (error < 0) { | ||
| 92 | dprintk("nfs_get_root: getattr error = %d\n", -error); | ||
| 93 | return ERR_PTR(error); | ||
| 94 | } | ||
| 95 | |||
| 96 | inode = nfs_fhget(sb, mntfh, fsinfo.fattr); | ||
| 97 | if (IS_ERR(inode)) { | ||
| 98 | dprintk("nfs_get_root: get root inode failed\n"); | ||
| 99 | return ERR_PTR(PTR_ERR(inode)); | ||
| 100 | } | ||
| 101 | |||
| 102 | /* root dentries normally start off anonymous and get spliced in later | ||
| 103 | * if the dentry tree reaches them; however if the dentry already | ||
| 104 | * exists, we'll pick it up at this point and use it as the root | ||
| 105 | */ | ||
| 106 | mntroot = d_alloc_anon(inode); | ||
| 107 | if (!mntroot) { | ||
| 108 | iput(inode); | ||
| 109 | dprintk("nfs_get_root: get root dentry failed\n"); | ||
| 110 | return ERR_PTR(-ENOMEM); | ||
| 111 | } | ||
| 112 | |||
| 113 | security_d_instantiate(mntroot, inode); | ||
| 114 | |||
| 115 | if (!mntroot->d_op) | ||
| 116 | mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops; | ||
| 117 | |||
| 118 | return mntroot; | ||
| 119 | } | ||
| 120 | |||
| 121 | #ifdef CONFIG_NFS_V4 | ||
| 122 | |||
| 123 | /* | ||
| 124 | * Do a simple pathwalk from the root FH of the server to the nominated target | ||
| 125 | * of the mountpoint | ||
| 126 | * - give error on symlinks | ||
| 127 | * - give error on ".." occurring in the path | ||
| 128 | * - follow traversals | ||
| 129 | */ | ||
| 130 | int nfs4_path_walk(struct nfs_server *server, | ||
| 131 | struct nfs_fh *mntfh, | ||
| 132 | const char *path) | ||
| 133 | { | ||
| 134 | struct nfs_fsinfo fsinfo; | ||
| 135 | struct nfs_fattr fattr; | ||
| 136 | struct nfs_fh lastfh; | ||
| 137 | struct qstr name; | ||
| 138 | int ret; | ||
| 139 | //int referral_count = 0; | ||
| 140 | |||
| 141 | dprintk("--> nfs4_path_walk(,,%s)\n", path); | ||
| 142 | |||
| 143 | fsinfo.fattr = &fattr; | ||
| 144 | nfs_fattr_init(&fattr); | ||
| 145 | |||
| 146 | if (*path++ != '/') { | ||
| 147 | dprintk("nfs4_get_root: Path does not begin with a slash\n"); | ||
| 148 | return -EINVAL; | ||
| 149 | } | ||
| 150 | |||
| 151 | /* Start by getting the root filehandle from the server */ | ||
| 152 | ret = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo); | ||
| 153 | if (ret < 0) { | ||
| 154 | dprintk("nfs4_get_root: getroot error = %d\n", -ret); | ||
| 155 | return ret; | ||
| 156 | } | ||
| 157 | |||
| 158 | if (fattr.type != NFDIR) { | ||
| 159 | printk(KERN_ERR "nfs4_get_root:" | ||
| 160 | " getroot encountered non-directory\n"); | ||
| 161 | return -ENOTDIR; | ||
| 162 | } | ||
| 163 | |||
| 164 | if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) { | ||
| 165 | printk(KERN_ERR "nfs4_get_root:" | ||
| 166 | " getroot obtained referral\n"); | ||
| 167 | return -EREMOTE; | ||
| 168 | } | ||
| 169 | |||
| 170 | next_component: | ||
| 171 | dprintk("Next: %s\n", path); | ||
| 172 | |||
| 173 | /* extract the next bit of the path */ | ||
| 174 | if (!*path) | ||
| 175 | goto path_walk_complete; | ||
| 176 | |||
| 177 | name.name = path; | ||
| 178 | while (*path && *path != '/') | ||
| 179 | path++; | ||
| 180 | name.len = path - (const char *) name.name; | ||
| 181 | |||
| 182 | eat_dot_dir: | ||
| 183 | while (*path == '/') | ||
| 184 | path++; | ||
| 185 | |||
| 186 | if (path[0] == '.' && (path[1] == '/' || !path[1])) { | ||
| 187 | path += 2; | ||
| 188 | goto eat_dot_dir; | ||
| 189 | } | ||
| 190 | |||
| 191 | if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || !path[2]) | ||
| 192 | ) { | ||
| 193 | printk(KERN_ERR "nfs4_get_root:" | ||
| 194 | " Mount path contains reference to \"..\"\n"); | ||
| 195 | return -EINVAL; | ||
| 196 | } | ||
| 197 | |||
| 198 | /* lookup the next FH in the sequence */ | ||
| 199 | memcpy(&lastfh, mntfh, sizeof(lastfh)); | ||
| 200 | |||
| 201 | dprintk("LookupFH: %*.*s [%s]\n", name.len, name.len, name.name, path); | ||
| 202 | |||
| 203 | ret = server->nfs_client->rpc_ops->lookupfh(server, &lastfh, &name, | ||
| 204 | mntfh, &fattr); | ||
| 205 | if (ret < 0) { | ||
| 206 | dprintk("nfs4_get_root: getroot error = %d\n", -ret); | ||
| 207 | return ret; | ||
| 208 | } | ||
| 209 | |||
| 210 | if (fattr.type != NFDIR) { | ||
| 211 | printk(KERN_ERR "nfs4_get_root:" | ||
| 212 | " lookupfh encountered non-directory\n"); | ||
| 213 | return -ENOTDIR; | ||
| 214 | } | ||
| 215 | |||
| 216 | if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) { | ||
| 217 | printk(KERN_ERR "nfs4_get_root:" | ||
| 218 | " lookupfh obtained referral\n"); | ||
| 219 | return -EREMOTE; | ||
| 220 | } | ||
| 221 | |||
| 222 | goto next_component; | ||
| 223 | |||
| 224 | path_walk_complete: | ||
| 225 | memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid)); | ||
| 226 | dprintk("<-- nfs4_path_walk() = 0\n"); | ||
| 227 | return 0; | ||
| 228 | } | ||
| 229 | |||
| 230 | /* | ||
| 231 | * get an NFS4 root dentry from the root filehandle | ||
| 232 | */ | ||
| 233 | struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh) | ||
| 234 | { | ||
| 235 | struct nfs_server *server = NFS_SB(sb); | ||
| 236 | struct nfs_fattr fattr; | ||
| 237 | struct dentry *mntroot; | ||
| 238 | struct inode *inode; | ||
| 239 | int error; | ||
| 240 | |||
| 241 | dprintk("--> nfs4_get_root()\n"); | ||
| 242 | |||
| 243 | /* create a dummy root dentry with dummy inode for this superblock */ | ||
| 244 | if (!sb->s_root) { | ||
| 245 | struct nfs_fh dummyfh; | ||
| 246 | struct dentry *root; | ||
| 247 | struct inode *iroot; | ||
| 248 | |||
| 249 | memset(&dummyfh, 0, sizeof(dummyfh)); | ||
| 250 | memset(&fattr, 0, sizeof(fattr)); | ||
| 251 | nfs_fattr_init(&fattr); | ||
| 252 | fattr.valid = NFS_ATTR_FATTR; | ||
| 253 | fattr.type = NFDIR; | ||
| 254 | fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR; | ||
| 255 | fattr.nlink = 2; | ||
| 256 | |||
| 257 | iroot = nfs_fhget(sb, &dummyfh, &fattr); | ||
| 258 | if (IS_ERR(iroot)) | ||
| 259 | return ERR_PTR(PTR_ERR(iroot)); | ||
| 260 | |||
| 261 | root = d_alloc_root(iroot); | ||
| 262 | if (!root) { | ||
| 263 | iput(iroot); | ||
| 264 | return ERR_PTR(-ENOMEM); | ||
| 265 | } | ||
| 266 | |||
| 267 | sb->s_root = root; | ||
| 268 | } | ||
| 269 | |||
| 270 | /* get the info about the server and filesystem */ | ||
| 271 | error = nfs4_server_capabilities(server, mntfh); | ||
| 272 | if (error < 0) { | ||
| 273 | dprintk("nfs_get_root: getcaps error = %d\n", | ||
| 274 | -error); | ||
| 275 | return ERR_PTR(error); | ||
| 276 | } | ||
| 277 | |||
| 278 | /* get the actual root for this mount */ | ||
| 279 | error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr); | ||
| 280 | if (error < 0) { | ||
| 281 | dprintk("nfs_get_root: getattr error = %d\n", -error); | ||
| 282 | return ERR_PTR(error); | ||
| 283 | } | ||
| 284 | |||
| 285 | inode = nfs_fhget(sb, mntfh, &fattr); | ||
| 286 | if (IS_ERR(inode)) { | ||
| 287 | dprintk("nfs_get_root: get root inode failed\n"); | ||
| 288 | return ERR_PTR(PTR_ERR(inode)); | ||
| 289 | } | ||
| 290 | |||
| 291 | /* root dentries normally start off anonymous and get spliced in later | ||
| 292 | * if the dentry tree reaches them; however if the dentry already | ||
| 293 | * exists, we'll pick it up at this point and use it as the root | ||
| 294 | */ | ||
| 295 | mntroot = d_alloc_anon(inode); | ||
| 296 | if (!mntroot) { | ||
| 297 | iput(inode); | ||
| 298 | dprintk("nfs_get_root: get root dentry failed\n"); | ||
| 299 | return ERR_PTR(-ENOMEM); | ||
| 300 | } | ||
| 301 | |||
| 302 | security_d_instantiate(mntroot, inode); | ||
| 303 | |||
| 304 | if (!mntroot->d_op) | ||
| 305 | mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops; | ||
| 306 | |||
| 307 | dprintk("<-- nfs4_get_root()\n"); | ||
| 308 | return mntroot; | ||
| 309 | } | ||
| 310 | |||
| 311 | #endif /* CONFIG_NFS_V4 */ | ||
| @@ -57,6 +57,20 @@ · 56 unmodified lines | |||
| 57 | /* Default cache timeout is 10 minutes */ | 57 | /* Default cache timeout is 10 minutes */ |
| 58 | unsigned int nfs_idmap_cache_timeout = 600 * HZ; | 58 | unsigned int nfs_idmap_cache_timeout = 600 * HZ; |
| 59 | 59 | ||
| 60 | static int param_set_idmap_timeout(const char *val, struct kernel_param *kp) | ||
| 61 | { | ||
| 62 | char *endp; | ||
| 63 | int num = simple_strtol(val, &endp, 0); | ||
| 64 | int jif = num * HZ; | ||
| 65 | if (endp == val || *endp || num < 0 || jif < num) | ||
| 66 | return -EINVAL; | ||
| 67 | *((int *)kp->arg) = jif; | ||
| 68 | return 0; | ||
| 69 | } | ||
| 70 | |||
| 71 | module_param_call(idmap_cache_timeout, param_set_idmap_timeout, param_get_int, | ||
| 72 | &nfs_idmap_cache_timeout, 0644); | ||
| 73 | |||
| 60 | struct idmap_hashent { | 74 | struct idmap_hashent { |
| 61 | unsigned long ih_expires; | 75 | unsigned long ih_expires; |
| 62 | __u32 ih_id; | 76 | __u32 ih_id; |
| @@ -70,7 +84,6 @@ struct idmap_hashtable { · 7 unmodified lines | |||
| 70 | }; | 84 | }; |
| 71 | 85 | ||
| 72 | struct idmap { | 86 | struct idmap { |
| 73 | char idmap_path[48]; | ||
| 74 | struct dentry *idmap_dentry; | 87 | struct dentry *idmap_dentry; |
| 75 | wait_queue_head_t idmap_wq; | 88 | wait_queue_head_t idmap_wq; |
| 76 | struct idmap_msg idmap_im; | 89 | struct idmap_msg idmap_im; |
| @@ -94,24 +107,23 @@ static struct rpc_pipe_ops idmap_upcall_ops = { · 17 unmodified lines | |||
| 94 | .destroy_msg = idmap_pipe_destroy_msg, | 107 | .destroy_msg = idmap_pipe_destroy_msg, |
| 95 | }; | 108 | }; |
| 96 | 109 | ||
| 97 | void | 110 | int |
| 98 | nfs_idmap_new(struct nfs4_client *clp) | 111 | nfs_idmap_new(struct nfs_client *clp) |
| 99 | { | 112 | { |
| 100 | struct idmap *idmap; | 113 | struct idmap *idmap; |
| 114 | int error; | ||
| 101 | 115 | ||
| 102 | if (clp->cl_idmap != NULL) | 116 | BUG_ON(clp->cl_idmap != NULL); |
| 103 | return; | ||
| 104 | if ((idmap = kzalloc(sizeof(*idmap), GFP_KERNEL)) == NULL) | ||
| 105 | return; | ||
| 106 | 117 | ||
| 107 | snprintf(idmap->idmap_path, sizeof(idmap->idmap_path), | 118 | if ((idmap = kzalloc(sizeof(*idmap), GFP_KERNEL)) == NULL) |
| 108 | "%s/idmap", clp->cl_rpcclient->cl_pathname); | 119 | return -ENOMEM; |
| 109 | 120 | ||
| 110 | idmap->idmap_dentry = rpc_mkpipe(idmap->idmap_path, | 121 | idmap->idmap_dentry = rpc_mkpipe(clp->cl_rpcclient->cl_dentry, "idmap", |
| 111 | idmap, &idmap_upcall_ops, 0); | 122 | idmap, &idmap_upcall_ops, 0); |
| 112 | if (IS_ERR(idmap->idmap_dentry)) { | 123 | if (IS_ERR(idmap->idmap_dentry)) { |
| 124 | error = PTR_ERR(idmap->idmap_dentry); | ||
| 113 | kfree(idmap); | 125 | kfree(idmap); |
| 114 | return; | 126 | return error; |
| 115 | } | 127 | } |
| 116 | 128 | ||
| 117 | mutex_init(&idmap->idmap_lock); | 129 | mutex_init(&idmap->idmap_lock); |
| @@ -121,10 +133,11 @@ nfs_idmap_new(struct nfs4_client *clp) · 3 unmodified lines | |||
| 121 | idmap->idmap_group_hash.h_type = IDMAP_TYPE_GROUP; | 133 | idmap->idmap_group_hash.h_type = IDMAP_TYPE_GROUP; |
| 122 | 134 | ||
| 123 | clp->cl_idmap = idmap; | 135 | clp->cl_idmap = idmap; |
| 136 | return 0; | ||
| 124 | } | 137 | } |
| 125 | 138 | ||
| 126 | void | 139 | void |
| 127 | nfs_idmap_delete(struct nfs4_client *clp) | 140 | nfs_idmap_delete(struct nfs_client *clp) |
| 128 | { | 141 | { |
| 129 | struct idmap *idmap = clp->cl_idmap; | 142 | struct idmap *idmap = clp->cl_idmap; |
| 130 | 143 | ||
| @@ -477,27 +490,27 @@ static unsigned int fnvhash32(const void *buf, size_t buflen) · 346 unmodified lines | |||
| 477 | return (hash); | 490 | return (hash); |
| 478 | } | 491 | } |
| 479 | 492 | ||
| 480 | int nfs_map_name_to_uid(struct nfs4_client *clp, const char *name, size_t namelen, __u32 *uid) | 493 | int nfs_map_name_to_uid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *uid) |
| 481 | { | 494 | { |
| 482 | struct idmap *idmap = clp->cl_idmap; | 495 | struct idmap *idmap = clp->cl_idmap; |
| 483 | 496 | ||
| 484 | return nfs_idmap_id(idmap, &idmap->idmap_user_hash, name, namelen, uid); | 497 | return nfs_idmap_id(idmap, &idmap->idmap_user_hash, name, namelen, uid); |
| 485 | } | 498 | } |
| 486 | 499 | ||
| 487 | int nfs_map_group_to_gid(struct nfs4_client *clp, const char *name, size_t namelen, __u32 *uid) | 500 | int nfs_map_group_to_gid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *uid) |
| 488 | { | 501 | { |
| 489 | struct idmap *idmap = clp->cl_idmap; | 502 | struct idmap *idmap = clp->cl_idmap; |
| 490 | 503 | ||
| 491 | return nfs_idmap_id(idmap, &idmap->idmap_group_hash, name, namelen, uid); | 504 | return nfs_idmap_id(idmap, &idmap->idmap_group_hash, name, namelen, uid); |
| 492 | } | 505 | } |
| 493 | 506 | ||
| 494 | int nfs_map_uid_to_name(struct nfs4_client *clp, __u32 uid, char *buf) | 507 | int nfs_map_uid_to_name(struct nfs_client *clp, __u32 uid, char *buf) |
| 495 | { | 508 | { |
| 496 | struct idmap *idmap = clp->cl_idmap; | 509 | struct idmap *idmap = clp->cl_idmap; |
| 497 | 510 | ||
| 498 | return nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf); | 511 | return nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf); |
| 499 | } | 512 | } |
| 500 | int nfs_map_gid_to_group(struct nfs4_client *clp, __u32 uid, char *buf) | 513 | int nfs_map_gid_to_group(struct nfs_client *clp, __u32 uid, char *buf) |
| 501 | { | 514 | { |
| 502 | struct idmap *idmap = clp->cl_idmap; | 515 | struct idmap *idmap = clp->cl_idmap; |
| 503 | 516 | ||
| @@ -76,19 +76,14 @@ int nfs_write_inode(struct inode *inode, int sync) · 75 unmodified lines | |||
| 76 | 76 | ||
| 77 | void nfs_clear_inode(struct inode *inode) | 77 | void nfs_clear_inode(struct inode *inode) |
| 78 | { | 78 | { |
| 79 | struct nfs_inode *nfsi = NFS_I(inode); | ||
| 80 | struct rpc_cred *cred; | ||
| 81 | |||
| 82 | /* | 79 | /* |
| 83 | * The following should never happen... | 80 | * The following should never happen... |
| 84 | */ | 81 | */ |
| 85 | BUG_ON(nfs_have_writebacks(inode)); | 82 | BUG_ON(nfs_have_writebacks(inode)); |
| 86 | BUG_ON (!list_empty(&nfsi->open_files)); | 83 | BUG_ON(!list_empty(&NFS_I(inode)->open_files)); |
| 84 | BUG_ON(atomic_read(&NFS_I(inode)->data_updates) != 0); | ||
| 87 | nfs_zap_acl_cache(inode); | 85 | nfs_zap_acl_cache(inode); |
| 88 | cred = nfsi->cache_access.cred; | 86 | nfs_access_zap_cache(inode); |
| 89 | if (cred) | ||
| 90 | put_rpccred(cred); | ||
| 91 | BUG_ON(atomic_read(&nfsi->data_updates) != 0); | ||
| 92 | } | 87 | } |
| 93 | 88 | ||
| 94 | /** | 89 | /** |
| @@ -242,13 +237,13 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) · 147 unmodified lines | |||
| 242 | /* Why so? Because we want revalidate for devices/FIFOs, and | 237 | /* Why so? Because we want revalidate for devices/FIFOs, and |
| 243 | * that's precisely what we have in nfs_file_inode_operations. | 238 | * that's precisely what we have in nfs_file_inode_operations. |
| 244 | */ | 239 | */ |
| 245 | inode->i_op = NFS_SB(sb)->rpc_ops->file_inode_ops; | 240 | inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->file_inode_ops; |
| 246 | if (S_ISREG(inode->i_mode)) { | 241 | if (S_ISREG(inode->i_mode)) { |
| 247 | inode->i_fop = &nfs_file_operations; | 242 | inode->i_fop = &nfs_file_operations; |
| 248 | inode->i_data.a_ops = &nfs_file_aops; | 243 | inode->i_data.a_ops = &nfs_file_aops; |
| 249 | inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info; | 244 | inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info; |
| 250 | } else if (S_ISDIR(inode->i_mode)) { | 245 | } else if (S_ISDIR(inode->i_mode)) { |
| 251 | inode->i_op = NFS_SB(sb)->rpc_ops->dir_inode_ops; | 246 | inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops; |
| 252 | inode->i_fop = &nfs_dir_operations; | 247 | inode->i_fop = &nfs_dir_operations; |
| 253 | if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS) | 248 | if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS) |
| 254 | && fattr->size <= NFS_LIMIT_READDIRPLUS) | 249 | && fattr->size <= NFS_LIMIT_READDIRPLUS) |
| @@ -290,7 +285,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) · 35 unmodified lines | |||
| 290 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); | 285 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); |
| 291 | nfsi->attrtimeo_timestamp = jiffies; | 286 | nfsi->attrtimeo_timestamp = jiffies; |
| 292 | memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); | 287 | memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); |
| 293 | nfsi->cache_access.cred = NULL; | 288 | nfsi->access_cache = RB_ROOT; |
| 294 | 289 | ||
| 295 | unlock_new_inode(inode); | 290 | unlock_new_inode(inode); |
| 296 | } else | 291 | } else |
| @@ -722,13 +717,11 @@ void nfs_end_data_update(struct inode *inode) · 425 unmodified lines | |||
| 722 | { | 717 | { |
| 723 | struct nfs_inode *nfsi = NFS_I(inode); | 718 | struct nfs_inode *nfsi = NFS_I(inode); |
| 724 | 719 | ||
| 725 | if (!nfs_have_delegation(inode, FMODE_READ)) { | 720 | /* Directories: invalidate page cache */ |
| 726 | /* Directories and symlinks: invalidate page cache */ | 721 | if (S_ISDIR(inode->i_mode)) { |
| 727 | if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) { | 722 | spin_lock(&inode->i_lock); |
| 728 | spin_lock(&inode->i_lock); | 723 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; |
| 729 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; | 724 | spin_unlock(&inode->i_lock); |
| 730 | spin_unlock(&inode->i_lock); | ||
| 731 | } | ||
| 732 | } | 725 | } |
| 733 | nfsi->cache_change_attribute = jiffies; | 726 | nfsi->cache_change_attribute = jiffies; |
| 734 | atomic_dec(&nfsi->data_updates); | 727 | atomic_dec(&nfsi->data_updates); |
| @@ -847,6 +840,12 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) · 112 unmodified lines | |||
| 847 | * | 840 | * |
| 848 | * After an operation that has changed the inode metadata, mark the | 841 | * After an operation that has changed the inode metadata, mark the |
| 849 | * attribute cache as being invalid, then try to update it. | 842 | * attribute cache as being invalid, then try to update it. |
| 843 | * | ||
| 844 | * NB: if the server didn't return any post op attributes, this | ||
| 845 | * function will force the retrieval of attributes before the next | ||
| 846 | * NFS request. Thus it should be used only for operations that | ||
| 847 | * are expected to change one or more attributes, to avoid | ||
| 848 | * unnecessary NFS requests and trips through nfs_update_inode(). | ||
| 850 | */ | 849 | */ |
| 851 | int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr) | 850 | int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr) |
| 852 | { | 851 | { |
| @@ -1025,7 +1024,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) · 172 unmodified lines | |||
| 1025 | out_fileid: | 1024 | out_fileid: |
| 1026 | printk(KERN_ERR "NFS: server %s error: fileid changed\n" | 1025 | printk(KERN_ERR "NFS: server %s error: fileid changed\n" |
| 1027 | "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", | 1026 | "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", |
| 1028 | NFS_SERVER(inode)->hostname, inode->i_sb->s_id, | 1027 | NFS_SERVER(inode)->nfs_client->cl_hostname, inode->i_sb->s_id, |
| 1029 | (long long)nfsi->fileid, (long long)fattr->fileid); | 1028 | (long long)nfsi->fileid, (long long)fattr->fileid); |
| 1030 | goto out_err; | 1029 | goto out_err; |
| 1031 | } | 1030 | } |
| @@ -1109,6 +1108,8 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) · 77 unmodified lines | |||
| 1109 | INIT_LIST_HEAD(&nfsi->dirty); | 1108 | INIT_LIST_HEAD(&nfsi->dirty); |
| 1110 | INIT_LIST_HEAD(&nfsi->commit); | 1109 | INIT_LIST_HEAD(&nfsi->commit); |
| 1111 | INIT_LIST_HEAD(&nfsi->open_files); | 1110 | INIT_LIST_HEAD(&nfsi->open_files); |
| 1111 | INIT_LIST_HEAD(&nfsi->access_cache_entry_lru); | ||
| 1112 | INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); | ||
| 1112 | INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC); | 1113 | INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC); |
| 1113 | atomic_set(&nfsi->data_updates, 0); | 1114 | atomic_set(&nfsi->data_updates, 0); |
| 1114 | nfsi->ndirty = 0; | 1115 | nfsi->ndirty = 0; |
| @@ -1144,6 +1145,10 @@ static int __init init_nfs_fs(void) · 29 unmodified lines | |||
| 1144 | { | 1145 | { |
| 1145 | int err; | 1146 | int err; |
| 1146 | 1147 | ||
| 1148 | err = nfs_fs_proc_init(); | ||
| 1149 | if (err) | ||
| 1150 | goto out5; | ||
| 1151 | |||
| 1147 | err = nfs_init_nfspagecache(); | 1152 | err = nfs_init_nfspagecache(); |
| 1148 | if (err) | 1153 | if (err) |
| 1149 | goto out4; | 1154 | goto out4; |
| @@ -1184,6 +1189,8 @@ out2: · 34 unmodified lines | |||
| 1184 | out3: | 1189 | out3: |
| 1185 | nfs_destroy_nfspagecache(); | 1190 | nfs_destroy_nfspagecache(); |
| 1186 | out4: | 1191 | out4: |
| 1192 | nfs_fs_proc_exit(); | ||
| 1193 | out5: | ||
| 1187 | return err; | 1194 | return err; |
| 1188 | } | 1195 | } |
| 1189 | 1196 | ||
| @@ -1198,6 +1205,7 @@ static void __exit exit_nfs_fs(void) · 8 unmodified lines | |||
| 1198 | rpc_proc_unregister("nfs"); | 1205 | rpc_proc_unregister("nfs"); |
| 1199 | #endif | 1206 | #endif |
| 1200 | unregister_nfs_fs(); | 1207 | unregister_nfs_fs(); |
| 1208 | nfs_fs_proc_exit(); | ||
| 1201 | } | 1209 | } |
| 1202 | 1210 | ||
| 1203 | /* Not quite true; I just maintain it */ | 1211 | /* Not quite true; I just maintain it */ |
| @@ -4,6 +4,18 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | #include <linux/mount.h> | 5 | #include <linux/mount.h> |
| 6 | 6 | ||
| 7 | struct nfs_string; | ||
| 8 | struct nfs_mount_data; | ||
| 9 | struct nfs4_mount_data; | ||
| 10 | |||
| 11 | /* Maximum number of readahead requests | ||
| 12 | * FIXME: this should really be a sysctl so that users may tune it to suit | ||
| 13 | * their needs. People that do NFS over a slow network, might for | ||
| 14 | * instance want to reduce it to something closer to 1 for improved | ||
| 15 | * interactive response. | ||
| 16 | */ | ||
| 17 | #define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) | ||
| 18 | |||
| 7 | struct nfs_clone_mount { | 19 | struct nfs_clone_mount { |
| 8 | const struct super_block *sb; | 20 | const struct super_block *sb; |
| 9 | const struct dentry *dentry; | 21 | const struct dentry *dentry; |
| @@ -15,7 +27,40 @@ struct nfs_clone_mount { · 5 unmodified lines | |||
| 15 | rpc_authflavor_t authflavor; | 27 | rpc_authflavor_t authflavor; |
| 16 | }; | 28 | }; |
| 17 | 29 | ||
| 18 | /* namespace-nfs4.c */ | 30 | /* client.c */ |
| 31 | extern struct rpc_program nfs_program; | ||
| 32 | |||
| 33 | extern void nfs_put_client(struct nfs_client *); | ||
| 34 | extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int); | ||
| 35 | extern struct nfs_server *nfs_create_server(const struct nfs_mount_data *, | ||
| 36 | struct nfs_fh *); | ||
| 37 | extern struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *, | ||
| 38 | const char *, | ||
| 39 | const struct sockaddr_in *, | ||
| 40 | const char *, | ||
| 41 | const char *, | ||
| 42 | rpc_authflavor_t, | ||
| 43 | struct nfs_fh *); | ||
| 44 | extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, | ||
| 45 | struct nfs_fh *); | ||
| 46 | extern void nfs_free_server(struct nfs_server *server); | ||
| 47 | extern struct nfs_server *nfs_clone_server(struct nfs_server *, | ||
| 48 | struct nfs_fh *, | ||
| 49 | struct nfs_fattr *); | ||
| 50 | #ifdef CONFIG_PROC_FS | ||
| 51 | extern int __init nfs_fs_proc_init(void); | ||
| 52 | extern void nfs_fs_proc_exit(void); | ||
| 53 | #else | ||
| 54 | static inline int nfs_fs_proc_init(void) | ||
| 55 | { | ||
| 56 | return 0; | ||
| 57 | } | ||
| 58 | static inline void nfs_fs_proc_exit(void) | ||
| 59 | { | ||
| 60 | } | ||
| 61 | #endif | ||
| 62 | |||
| 63 | /* nfs4namespace.c */ | ||
| 19 | #ifdef CONFIG_NFS_V4 | 64 | #ifdef CONFIG_NFS_V4 |
| 20 | extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry); | 65 | extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry); |
| 21 | #else | 66 | #else |
| @@ -46,6 +91,7 @@ extern void nfs_destroy_directcache(void); · 24 unmodified lines | |||
| 46 | #endif | 91 | #endif |
| 47 | 92 | ||
| 48 | /* nfs2xdr.c */ | 93 | /* nfs2xdr.c */ |
| 94 | extern int nfs_stat_to_errno(int); | ||
| 49 | extern struct rpc_procinfo nfs_procedures[]; | 95 | extern struct rpc_procinfo nfs_procedures[]; |
| 50 | extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int); | 96 | extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int); |
| 51 | 97 | ||
| @@ -54,8 +100,9 @@ extern struct rpc_procinfo nfs3_procedures[]; · 2 unmodified lines | |||
| 54 | extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int); | 100 | extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int); |
| 55 | 101 | ||
| 56 | /* nfs4xdr.c */ | 102 | /* nfs4xdr.c */ |
| 57 | extern int nfs_stat_to_errno(int); | 103 | #ifdef CONFIG_NFS_V4 |
| 58 | extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus); | 104 | extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus); |
| 105 | #endif | ||
| 59 | 106 | ||
| 60 | /* nfs4proc.c */ | 107 | /* nfs4proc.c */ |
| 61 | #ifdef CONFIG_NFS_V4 | 108 | #ifdef CONFIG_NFS_V4 |
| @@ -66,6 +113,9 @@ extern int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry, · 4 unmodified lines | |||
| 66 | struct page *page); | 113 | struct page *page); |
| 67 | #endif | 114 | #endif |
| 68 | 115 | ||
| 116 | /* dir.c */ | ||
| 117 | extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask); | ||
| 118 | |||
| 69 | /* inode.c */ | 119 | /* inode.c */ |
| 70 | extern struct inode *nfs_alloc_inode(struct super_block *sb); | 120 | extern struct inode *nfs_alloc_inode(struct super_block *sb); |
| 71 | extern void nfs_destroy_inode(struct inode *); | 121 | extern void nfs_destroy_inode(struct inode *); |
| @@ -76,10 +126,10 @@ extern void nfs4_clear_inode(struct inode *); · 4 unmodified lines | |||
| 76 | #endif | 126 | #endif |
| 77 | 127 | ||
| 78 | /* super.c */ | 128 | /* super.c */ |
| 79 | extern struct file_system_type nfs_referral_nfs4_fs_type; | 129 | extern struct file_system_type nfs_xdev_fs_type; |
| 80 | extern struct file_system_type clone_nfs_fs_type; | ||
| 81 | #ifdef CONFIG_NFS_V4 | 130 | #ifdef CONFIG_NFS_V4 |
| 82 | extern struct file_system_type clone_nfs4_fs_type; | 131 | extern struct file_system_type nfs4_xdev_fs_type; |
| 132 | extern struct file_system_type nfs4_referral_fs_type; | ||
| 83 | #endif | 133 | #endif |
| 84 | 134 | ||
| 85 | extern struct rpc_stat nfs_rpcstat; | 135 | extern struct rpc_stat nfs_rpcstat; |
| @@ -88,30 +138,30 @@ extern int __init register_nfs_fs(void); · 2 unmodified lines | |||
| 88 | extern void __exit unregister_nfs_fs(void); | 138 | extern void __exit unregister_nfs_fs(void); |
| 89 | 139 | ||
| 90 | /* namespace.c */ | 140 | /* namespace.c */ |
| 91 | extern char *nfs_path(const char *base, const struct dentry *dentry, | 141 | extern char *nfs_path(const char *base, |
| 142 | const struct dentry *droot, | ||
| 143 | const struct dentry *dentry, | ||
| 92 | char *buffer, ssize_t buflen); | 144 | char *buffer, ssize_t buflen); |
| 93 | 145 | ||
| 94 | /* | 146 | /* getroot.c */ |
| 95 | * Determine the mount path as a string | 147 | extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *); |
| 96 | */ | ||
| 97 | static inline char * | ||
| 98 | nfs4_path(const struct dentry *dentry, char *buffer, ssize_t buflen) | ||
| 99 | { | ||
| 100 | #ifdef CONFIG_NFS_V4 | 148 | #ifdef CONFIG_NFS_V4 |
| 101 | return nfs_path(NFS_SB(dentry->d_sb)->mnt_path, dentry, buffer, buflen); | 149 | extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *); |
| 102 | #else | 150 | |
| 103 | return NULL; | 151 | extern int nfs4_path_walk(struct nfs_server *server, |
| 152 | struct nfs_fh *mntfh, | ||
| 153 | const char *path); | ||
| 104 | #endif | 154 | #endif |
| 105 | } | ||
| 106 | 155 | ||
| 107 | /* | 156 | /* |
| 108 | * Determine the device name as a string | 157 | * Determine the device name as a string |
| 109 | */ | 158 | */ |
| 110 | static inline char *nfs_devname(const struct vfsmount *mnt_parent, | 159 | static inline char *nfs_devname(const struct vfsmount *mnt_parent, |
| 111 | const struct dentry *dentry, | 160 | const struct dentry *dentry, |
| 112 | char *buffer, ssize_t buflen) | 161 | char *buffer, ssize_t buflen) |
| 113 | { | 162 | { |
| 114 | return nfs_path(mnt_parent->mnt_devname, dentry, buffer, buflen); | 163 | return nfs_path(mnt_parent->mnt_devname, mnt_parent->mnt_root, |
| 164 | dentry, buffer, buflen); | ||
| 115 | } | 165 | } |
| 116 | 166 | ||
| 117 | /* | 167 | /* |
| @@ -167,20 +217,3 @@ void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize) · 49 unmodified lines | |||
| 167 | if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0) | 217 | if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0) |
| 168 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 218 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
| 169 | } | 219 | } |
| 170 | |||
| 171 | /* | ||
| 172 | * Check if the string represents a "valid" IPv4 address | ||
| 173 | */ | ||
| 174 | static inline int valid_ipaddr4(const char *buf) | ||
| 175 | { | ||
| 176 | int rc, count, in[4]; | ||
| 177 | |||
| 178 | rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]); | ||
| 179 | if (rc != 4) | ||
| 180 | return -EINVAL; | ||
| 181 | for (count = 0; count < 4; count++) { | ||
| 182 | if (in[count] > 255) | ||
| 183 | return -EINVAL; | ||
| 184 | } | ||
| 185 | return 0; | ||
| 186 | } | ||
| @@ -14,7 +14,6 @@ · 13 unmodified lines | |||
| 14 | #include <linux/net.h> | 14 | #include <linux/net.h> |
| 15 | #include <linux/in.h> | 15 | #include <linux/in.h> |
| 16 | #include <linux/sunrpc/clnt.h> | 16 | #include <linux/sunrpc/clnt.h> |
| 17 | #include <linux/sunrpc/xprt.h> | ||
| 18 | #include <linux/sunrpc/sched.h> | 17 | #include <linux/sunrpc/sched.h> |
| 19 | #include <linux/nfs_fs.h> | 18 | #include <linux/nfs_fs.h> |
| 20 | 19 | ||
| @@ -77,22 +76,19 @@ static struct rpc_clnt * · 56 unmodified lines | |||
| 77 | mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version, | 76 | mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version, |
| 78 | int protocol) | 77 | int protocol) |
| 79 | { | 78 | { |
| 80 | struct rpc_xprt *xprt; | 79 | struct rpc_create_args args = { |
| 81 | struct rpc_clnt *clnt; | 80 | .protocol = protocol, |
| 82 | 81 | .address = (struct sockaddr *)srvaddr, | |
| 83 | xprt = xprt_create_proto(protocol, srvaddr, NULL); | 82 | .addrsize = sizeof(*srvaddr), |
| 84 | if (IS_ERR(xprt)) | 83 | .servername = hostname, |
| 85 | return (struct rpc_clnt *)xprt; | 84 | .program = &mnt_program, |
| 86 | 85 | .version = version, | |
| 87 | clnt = rpc_create_client(xprt, hostname, | 86 | .authflavor = RPC_AUTH_UNIX, |
| 88 | &mnt_program, version, | 87 | .flags = (RPC_CLNT_CREATE_ONESHOT | |
| 89 | RPC_AUTH_UNIX); | 88 | RPC_CLNT_CREATE_INTR), |
| 90 | if (!IS_ERR(clnt)) { | 89 | }; |
| 91 | clnt->cl_softrtry = 1; | 90 | |
| 92 | clnt->cl_oneshot = 1; | 91 | return rpc_create(&args); |
| 93 | clnt->cl_intr = 1; | ||
| 94 | } | ||
| 95 | return clnt; | ||
| 96 | } | 92 | } |
| 97 | 93 | ||
| 98 | /* | 94 | /* |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | * linux/fs/nfs/namespace.c | 2 | * linux/fs/nfs/namespace.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com> | 4 | * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com> |
| 5 | * - Modified by David Howells <dhowells@redhat.com> | ||
| 5 | * | 6 | * |
| 6 | * NFS namespace | 7 | * NFS namespace |
| 7 | */ | 8 | */ |
| @@ -28,6 +29,7 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ; · 20 unmodified lines | |||
| 28 | /* | 29 | /* |
| 29 | * nfs_path - reconstruct the path given an arbitrary dentry | 30 | * nfs_path - reconstruct the path given an arbitrary dentry |
| 30 | * @base - arbitrary string to prepend to the path | 31 | * @base - arbitrary string to prepend to the path |
| 32 | * @droot - pointer to root dentry for mountpoint | ||
| 31 | * @dentry - pointer to dentry | 33 | * @dentry - pointer to dentry |
| 32 | * @buffer - result buffer | 34 | * @buffer - result buffer |
| 33 | * @buflen - length of buffer | 35 | * @buflen - length of buffer |
| @@ -38,7 +40,9 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ; · 4 unmodified lines | |||
| 38 | * This is mainly for use in figuring out the path on the | 40 | * This is mainly for use in figuring out the path on the |
| 39 | * server side when automounting on top of an existing partition. | 41 | * server side when automounting on top of an existing partition. |
| 40 | */ | 42 | */ |
| 41 | char *nfs_path(const char *base, const struct dentry *dentry, | 43 | char *nfs_path(const char *base, |
| 44 | const struct dentry *droot, | ||
| 45 | const struct dentry *dentry, | ||
| 42 | char *buffer, ssize_t buflen) | 46 | char *buffer, ssize_t buflen) |
| 43 | { | 47 | { |
| 44 | char *end = buffer+buflen; | 48 | char *end = buffer+buflen; |
| @@ -47,7 +51,7 @@ char *nfs_path(const char *base, const struct dentry *dentry, · 2 unmodified lines | |||
| 47 | *--end = '\0'; | 51 | *--end = '\0'; |
| 48 | buflen--; | 52 | buflen--; |
| 49 | spin_lock(&dcache_lock); | 53 | spin_lock(&dcache_lock); |
| 50 | while (!IS_ROOT(dentry)) { | 54 | while (!IS_ROOT(dentry) && dentry != droot) { |
| 51 | namelen = dentry->d_name.len; | 55 | namelen = dentry->d_name.len; |
| 52 | buflen -= namelen + 1; | 56 | buflen -= namelen + 1; |
| 53 | if (buflen < 0) | 57 | if (buflen < 0) |
| @@ -96,15 +100,18 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) · 42 unmodified lines | |||
| 96 | struct nfs_fattr fattr; | 100 | struct nfs_fattr fattr; |
| 97 | int err; | 101 | int err; |
| 98 | 102 | ||
| 103 | dprintk("--> nfs_follow_mountpoint()\n"); | ||
| 104 | |||
| 99 | BUG_ON(IS_ROOT(dentry)); | 105 | BUG_ON(IS_ROOT(dentry)); |
| 100 | dprintk("%s: enter\n", __FUNCTION__); | 106 | dprintk("%s: enter\n", __FUNCTION__); |
| 101 | dput(nd->dentry); | 107 | dput(nd->dentry); |
| 102 | nd->dentry = dget(dentry); | 108 | nd->dentry = dget(dentry); |
| 103 | if (d_mountpoint(nd->dentry)) | 109 | |
| 104 | goto out_follow; | ||
| 105 | /* Look it up again */ | 110 | /* Look it up again */ |
| 106 | parent = dget_parent(nd->dentry); | 111 | parent = dget_parent(nd->dentry); |
| 107 | err = server->rpc_ops->lookup(parent->d_inode, &nd->dentry->d_name, &fh, &fattr); | 112 | err = server->nfs_client->rpc_ops->lookup(parent->d_inode, |
| 113 | &nd->dentry->d_name, | ||
| 114 | &fh, &fattr); | ||
| 108 | dput(parent); | 115 | dput(parent); |
| 109 | if (err != 0) | 116 | if (err != 0) |
| 110 | goto out_err; | 117 | goto out_err; |
| @@ -132,6 +139,8 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) · 21 unmodified lines | |||
| 132 | schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); | 139 | schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); |
| 133 | out: | 140 | out: |
| 134 | dprintk("%s: done, returned %d\n", __FUNCTION__, err); | 141 | dprintk("%s: done, returned %d\n", __FUNCTION__, err); |
| 142 | |||
| 143 | dprintk("<-- nfs_follow_mountpoint() = %d\n", err); | ||
| 135 | return ERR_PTR(err); | 144 | return ERR_PTR(err); |
| 136 | out_err: | 145 | out_err: |
| 137 | path_release(nd); | 146 | path_release(nd); |
| @@ -172,22 +181,23 @@ void nfs_release_automount_timer(void) · 34 unmodified lines | |||
| 172 | /* | 181 | /* |
| 173 | * Clone a mountpoint of the appropriate type | 182 | * Clone a mountpoint of the appropriate type |
| 174 | */ | 183 | */ |
| 175 | static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server, char *devname, | 184 | static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server, |
| 185 | const char *devname, | ||
| 176 | struct nfs_clone_mount *mountdata) | 186 | struct nfs_clone_mount *mountdata) |
| 177 | { | 187 | { |
| 178 | #ifdef CONFIG_NFS_V4 | 188 | #ifdef CONFIG_NFS_V4 |
| 179 | struct vfsmount *mnt = NULL; | 189 | struct vfsmount *mnt = NULL; |
| 180 | switch (server->rpc_ops->version) { | 190 | switch (server->nfs_client->cl_nfsversion) { |
| 181 | case 2: | 191 | case 2: |
| 182 | case 3: | 192 | case 3: |
| 183 | mnt = vfs_kern_mount(&clone_nfs_fs_type, 0, devname, mountdata); | 193 | mnt = vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata); |
| 184 | break; | 194 | break; |
| 185 | case 4: | 195 | case 4: |
| 186 | mnt = vfs_kern_mount(&clone_nfs4_fs_type, 0, devname, mountdata); | 196 | mnt = vfs_kern_mount(&nfs4_xdev_fs_type, 0, devname, mountdata); |
| 187 | } | 197 | } |
| 188 | return mnt; | 198 | return mnt; |
| 189 | #else | 199 | #else |
| 190 | return vfs_kern_mount(&clone_nfs_fs_type, 0, devname, mountdata); | 200 | return vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata); |
| 191 | #endif | 201 | #endif |
| 192 | } | 202 | } |
| 193 | 203 | ||
| @@ -213,6 +223,8 @@ struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, · 19 unmodified lines | |||
| 213 | char *page = (char *) __get_free_page(GFP_USER); | 223 | char *page = (char *) __get_free_page(GFP_USER); |
| 214 | char *devname; | 224 | char *devname; |
| 215 | 225 | ||
| 226 | dprintk("--> nfs_do_submount()\n"); | ||
| 227 | |||
| 216 | dprintk("%s: submounting on %s/%s\n", __FUNCTION__, | 228 | dprintk("%s: submounting on %s/%s\n", __FUNCTION__, |
| 217 | dentry->d_parent->d_name.name, | 229 | dentry->d_parent->d_name.name, |
| 218 | dentry->d_name.name); | 230 | dentry->d_name.name); |
| @@ -227,5 +239,7 @@ free_page: · 8 unmodified lines | |||
| 227 | free_page((unsigned long)page); | 239 | free_page((unsigned long)page); |
| 228 | out: | 240 | out: |
| 229 | dprintk("%s: done\n", __FUNCTION__); | 241 | dprintk("%s: done\n", __FUNCTION__); |
| 242 | |||
| 243 | dprintk("<-- nfs_do_submount() = %p\n", mnt); | ||
| 230 | return mnt; | 244 | return mnt; |
| 231 | } | 245 | } |
| @@ -51,7 +51,7 @@ · 50 unmodified lines | |||
| 51 | #define NFS_createargs_sz (NFS_diropargs_sz+NFS_sattr_sz) | 51 | #define NFS_createargs_sz (NFS_diropargs_sz+NFS_sattr_sz) |
| 52 | #define NFS_renameargs_sz (NFS_diropargs_sz+NFS_diropargs_sz) | 52 | #define NFS_renameargs_sz (NFS_diropargs_sz+NFS_diropargs_sz) |
| 53 | #define NFS_linkargs_sz (NFS_fhandle_sz+NFS_diropargs_sz) | 53 | #define NFS_linkargs_sz (NFS_fhandle_sz+NFS_diropargs_sz) |
| 54 | #define NFS_symlinkargs_sz (NFS_diropargs_sz+NFS_path_sz+NFS_sattr_sz) | 54 | #define NFS_symlinkargs_sz (NFS_diropargs_sz+1+NFS_sattr_sz) |
| 55 | #define NFS_readdirargs_sz (NFS_fhandle_sz+2) | 55 | #define NFS_readdirargs_sz (NFS_fhandle_sz+2) |
| 56 | 56 | ||
| 57 | #define NFS_attrstat_sz (1+NFS_fattr_sz) | 57 | #define NFS_attrstat_sz (1+NFS_fattr_sz) |
| @@ -351,11 +351,26 @@ nfs_xdr_linkargs(struct rpc_rqst *req, u32 *p, struct nfs_linkargs *args) · 293 unmodified lines | |||
| 351 | static int | 351 | static int |
| 352 | nfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args) | 352 | nfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args) |
| 353 | { | 353 | { |
| 354 | struct xdr_buf *sndbuf = &req->rq_snd_buf; | ||
| 355 | size_t pad; | ||
| 356 | |||
| 354 | p = xdr_encode_fhandle(p, args->fromfh); | 357 | p = xdr_encode_fhandle(p, args->fromfh); |
| 355 | p = xdr_encode_array(p, args->fromname, args->fromlen); | 358 | p = xdr_encode_array(p, args->fromname, args->fromlen); |
| 356 | p = xdr_encode_array(p, args->topath, args->tolen); | 359 | *p++ = htonl(args->pathlen); |
| 360 | sndbuf->len = xdr_adjust_iovec(sndbuf->head, p); | ||
| 361 | |||
| 362 | xdr_encode_pages(sndbuf, args->pages, 0, args->pathlen); | ||
| 363 | |||
| 364 | /* | ||
| 365 | * xdr_encode_pages may have added a few bytes to ensure the | ||
| 366 | * pathname ends on a 4-byte boundary. Start encoding the | ||
| 367 | * attributes after the pad bytes. | ||
| 368 | */ | ||
| 369 | pad = sndbuf->tail->iov_len; | ||
| 370 | if (pad > 0) | ||
| 371 | p++; | ||
| 357 | p = xdr_encode_sattr(p, args->sattr); | 372 | p = xdr_encode_sattr(p, args->sattr); |
| 358 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); | 373 | sndbuf->len += xdr_adjust_iovec(sndbuf->tail, p) - pad; |
| 359 | return 0; | 374 | return 0; |
| 360 | } | 375 | } |
| 361 | 376 | ||
| @@ -81,7 +81,7 @@ do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle, · 80 unmodified lines | |||
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | /* | 83 | /* |
| 84 | * Bare-bones access to getattr: this is for nfs_read_super. | 84 | * Bare-bones access to getattr: this is for nfs_get_root/nfs_get_sb |
| 85 | */ | 85 | */ |
| 86 | static int | 86 | static int |
| 87 | nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, | 87 | nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, |
| @@ -90,8 +90,8 @@ nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, · 2 unmodified lines | |||
| 90 | int status; | 90 | int status; |
| 91 | 91 | ||
| 92 | status = do_proc_get_root(server->client, fhandle, info); | 92 | status = do_proc_get_root(server->client, fhandle, info); |
| 93 | if (status && server->client_sys != server->client) | 93 | if (status && server->nfs_client->cl_rpcclient != server->client) |
| 94 | status = do_proc_get_root(server->client_sys, fhandle, info); | 94 | status = do_proc_get_root(server->nfs_client->cl_rpcclient, fhandle, info); |
| 95 | return status; | 95 | return status; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| @@ -544,23 +544,23 @@ nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) · 446 unmodified lines | |||
| 544 | } | 544 | } |
| 545 | 545 | ||
| 546 | static int | 546 | static int |
| 547 | nfs3_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path, | 547 | nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, |
| 548 | struct iattr *sattr, struct nfs_fh *fhandle, | 548 | unsigned int len, struct iattr *sattr) |
| 549 | struct nfs_fattr *fattr) | ||
| 550 | { | 549 | { |
| 551 | struct nfs_fattr dir_attr; | 550 | struct nfs_fh fhandle; |
| 551 | struct nfs_fattr fattr, dir_attr; | ||
| 552 | struct nfs3_symlinkargs arg = { | 552 | struct nfs3_symlinkargs arg = { |
| 553 | .fromfh = NFS_FH(dir), | 553 | .fromfh = NFS_FH(dir), |
| 554 | .fromname = name->name, | 554 | .fromname = dentry->d_name.name, |
| 555 | .fromlen = name->len, | 555 | .fromlen = dentry->d_name.len, |
| 556 | .topath = path->name, | 556 | .pages = &page, |
| 557 | .tolen = path->len, | 557 | .pathlen = len, |
| 558 | .sattr = sattr | 558 | .sattr = sattr |
| 559 | }; | 559 | }; |
| 560 | struct nfs3_diropres res = { | 560 | struct nfs3_diropres res = { |
| 561 | .dir_attr = &dir_attr, | 561 | .dir_attr = &dir_attr, |
| 562 | .fh = fhandle, | 562 | .fh = &fhandle, |
| 563 | .fattr = fattr | 563 | .fattr = &fattr |
| 564 | }; | 564 | }; |
| 565 | struct rpc_message msg = { | 565 | struct rpc_message msg = { |
| 566 | .rpc_proc = &nfs3_procedures[NFS3PROC_SYMLINK], | 566 | .rpc_proc = &nfs3_procedures[NFS3PROC_SYMLINK], |
| @@ -569,13 +569,19 @@ nfs3_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path, · 2 unmodified lines | |||
| 569 | }; | 569 | }; |
| 570 | int status; | 570 | int status; |
| 571 | 571 | ||
| 572 | if (path->len > NFS3_MAXPATHLEN) | 572 | if (len > NFS3_MAXPATHLEN) |
| 573 | return -ENAMETOOLONG; | 573 | return -ENAMETOOLONG; |
| 574 | dprintk("NFS call symlink %s -> %s\n", name->name, path->name); | 574 | |
| 575 | dprintk("NFS call symlink %s\n", dentry->d_name.name); | ||
| 576 | |||
| 575 | nfs_fattr_init(&dir_attr); | 577 | nfs_fattr_init(&dir_attr); |
| 576 | nfs_fattr_init(fattr); | 578 | nfs_fattr_init(&fattr); |
| 577 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 579 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
| 578 | nfs_post_op_update_inode(dir, &dir_attr); | 580 | nfs_post_op_update_inode(dir, &dir_attr); |
| 581 | if (status != 0) | ||
| 582 | goto out; | ||
| 583 | status = nfs_instantiate(dentry, &fhandle, &fattr); | ||
| 584 | out: | ||
| 579 | dprintk("NFS reply symlink: %d\n", status); | 585 | dprintk("NFS reply symlink: %d\n", status); |
| 580 | return status; | 586 | return status; |
| 581 | } | 587 | } |
| @@ -785,7 +791,7 @@ nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, · 203 unmodified lines | |||
| 785 | 791 | ||
| 786 | dprintk("NFS call fsinfo\n"); | 792 | dprintk("NFS call fsinfo\n"); |
| 787 | nfs_fattr_init(info->fattr); | 793 | nfs_fattr_init(info->fattr); |
| 788 | status = rpc_call_sync(server->client_sys, &msg, 0); | 794 | status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0); |
| 789 | dprintk("NFS reply fsinfo: %d\n", status); | 795 | dprintk("NFS reply fsinfo: %d\n", status); |
| 790 | return status; | 796 | return status; |
| 791 | } | 797 | } |
| @@ -886,7 +892,7 @@ nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl) · 94 unmodified lines | |||
| 886 | return nlmclnt_proc(filp->f_dentry->d_inode, cmd, fl); | 892 | return nlmclnt_proc(filp->f_dentry->d_inode, cmd, fl); |
| 887 | } | 893 | } |
| 888 | 894 | ||
| 889 | struct nfs_rpc_ops nfs_v3_clientops = { | 895 | const struct nfs_rpc_ops nfs_v3_clientops = { |
| 890 | .version = 3, /* protocol version */ | 896 | .version = 3, /* protocol version */ |
| 891 | .dentry_ops = &nfs_dentry_operations, | 897 | .dentry_ops = &nfs_dentry_operations, |
| 892 | .dir_inode_ops = &nfs3_dir_inode_operations, | 898 | .dir_inode_ops = &nfs3_dir_inode_operations, |
| @@ -56,7 +56,7 @@ · 55 unmodified lines | |||
| 56 | #define NFS3_writeargs_sz (NFS3_fh_sz+5) | 56 | #define NFS3_writeargs_sz (NFS3_fh_sz+5) |
| 57 | #define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) | 57 | #define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) |
| 58 | #define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) | 58 | #define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) |
| 59 | #define NFS3_symlinkargs_sz (NFS3_diropargs_sz+NFS3_path_sz+NFS3_sattr_sz) | 59 | #define NFS3_symlinkargs_sz (NFS3_diropargs_sz+1+NFS3_sattr_sz) |
| 60 | #define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz) | 60 | #define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz) |
| 61 | #define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz) | 61 | #define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz) |
| 62 | #define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz) | 62 | #define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz) |
| @@ -398,8 +398,11 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs3_symlinkargs *args · 335 unmodified lines | |||
| 398 | p = xdr_encode_fhandle(p, args->fromfh); | 398 | p = xdr_encode_fhandle(p, args->fromfh); |
| 399 | p = xdr_encode_array(p, args->fromname, args->fromlen); | 399 | p = xdr_encode_array(p, args->fromname, args->fromlen); |
| 400 | p = xdr_encode_sattr(p, args->sattr); | 400 | p = xdr_encode_sattr(p, args->sattr); |
| 401 | p = xdr_encode_array(p, args->topath, args->tolen); | 401 | *p++ = htonl(args->pathlen); |
| 402 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); | 402 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); |
| 403 | |||
| 404 | /* Copy the page */ | ||
| 405 | xdr_encode_pages(&req->rq_snd_buf, args->pages, 0, args->pathlen); | ||
| 403 | return 0; | 406 | return 0; |
| 404 | } | 407 | } |
| 405 | 408 | ||
| @@ -42,55 +42,6 @@ enum nfs4_client_state { · 41 unmodified lines | |||
| 42 | NFS4CLNT_LEASE_EXPIRED, | 42 | NFS4CLNT_LEASE_EXPIRED, |
| 43 | }; | 43 | }; |
| 44 | 44 | ||
| 45 | /* | ||
| 46 | * The nfs4_client identifies our client state to the server. | ||
| 47 | */ | ||
| 48 | struct nfs4_client { | ||
| 49 | struct list_head cl_servers; /* Global list of servers */ | ||
| 50 | struct in_addr cl_addr; /* Server identifier */ | ||
| 51 | u64 cl_clientid; /* constant */ | ||
| 52 | nfs4_verifier cl_confirm; | ||
| 53 | unsigned long cl_state; | ||
| 54 | |||
| 55 | u32 cl_lockowner_id; | ||
| 56 | |||
| 57 | /* | ||
| 58 | * The following rwsem ensures exclusive access to the server | ||
| 59 | * while we recover the state following a lease expiration. | ||
| 60 | */ | ||
| 61 | struct rw_semaphore cl_sem; | ||
| 62 | |||
| 63 | struct list_head cl_delegations; | ||
| 64 | struct list_head cl_state_owners; | ||
| 65 | struct list_head cl_unused; | ||
| 66 | int cl_nunused; | ||
| 67 | spinlock_t cl_lock; | ||
| 68 | atomic_t cl_count; | ||
| 69 | |||
| 70 | struct rpc_clnt * cl_rpcclient; | ||
| 71 | |||
| 72 | struct list_head cl_superblocks; /* List of nfs_server structs */ | ||
| 73 | |||
| 74 | unsigned long cl_lease_time; | ||
| 75 | unsigned long cl_last_renewal; | ||
| 76 | struct work_struct cl_renewd; | ||
| 77 | struct work_struct cl_recoverd; | ||
| 78 | |||
| 79 | struct rpc_wait_queue cl_rpcwaitq; | ||
| 80 | |||
| 81 | /* used for the setclientid verifier */ | ||
| 82 | struct timespec cl_boot_time; | ||
| 83 | |||
| 84 | /* idmapper */ | ||
| 85 | struct idmap * cl_idmap; | ||
| 86 | |||
| 87 | /* Our own IP address, as a null-terminated string. | ||
| 88 | * This is used to generate the clientid, and the callback address. | ||
| 89 | */ | ||
| 90 | char cl_ipaddr[16]; | ||
| 91 | unsigned char cl_id_uniquifier; | ||
| 92 | }; | ||
| 93 | |||
| 94 | /* | 45 | /* |
| 95 | * struct rpc_sequence ensures that RPC calls are sent in the exact | 46 | * struct rpc_sequence ensures that RPC calls are sent in the exact |
| 96 | * order that they appear on the list. | 47 | * order that they appear on the list. |
| @@ -127,7 +78,7 @@ static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status · 30 unmodified lines | |||
| 127 | struct nfs4_state_owner { | 78 | struct nfs4_state_owner { |
| 128 | spinlock_t so_lock; | 79 | spinlock_t so_lock; |
| 129 | struct list_head so_list; /* per-clientid list of state_owners */ | 80 | struct list_head so_list; /* per-clientid list of state_owners */ |
| 130 | struct nfs4_client *so_client; | 81 | struct nfs_client *so_client; |
| 131 | u32 so_id; /* 32-bit identifier, unique */ | 82 | u32 so_id; /* 32-bit identifier, unique */ |
| 132 | atomic_t so_count; | 83 | atomic_t so_count; |
| 133 | 84 | ||
| @@ -210,10 +161,10 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t); · 76 unmodified lines | |||
| 210 | 161 | ||
| 211 | /* nfs4proc.c */ | 162 | /* nfs4proc.c */ |
| 212 | extern int nfs4_map_errors(int err); | 163 | extern int nfs4_map_errors(int err); |
| 213 | extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short, struct rpc_cred *); | 164 | extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *); |
| 214 | extern int nfs4_proc_setclientid_confirm(struct nfs4_client *, struct rpc_cred *); | 165 | extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *); |
| 215 | extern int nfs4_proc_async_renew(struct nfs4_client *, struct rpc_cred *); | 166 | extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *); |
| 216 | extern int nfs4_proc_renew(struct nfs4_client *, struct rpc_cred *); | 167 | extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); |
| 217 | extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state); | 168 | extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state); |
| 218 | extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); | 169 | extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); |
| 219 | extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); | 170 | extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); |
| @@ -231,19 +182,14 @@ extern const u32 nfs4_fsinfo_bitmap[2]; · 11 unmodified lines | |||
| 231 | extern const u32 nfs4_fs_locations_bitmap[2]; | 182 | extern const u32 nfs4_fs_locations_bitmap[2]; |
| 232 | 183 | ||
| 233 | /* nfs4renewd.c */ | 184 | /* nfs4renewd.c */ |
| 234 | extern void nfs4_schedule_state_renewal(struct nfs4_client *); | 185 | extern void nfs4_schedule_state_renewal(struct nfs_client *); |
| 235 | extern void nfs4_renewd_prepare_shutdown(struct nfs_server *); | 186 | extern void nfs4_renewd_prepare_shutdown(struct nfs_server *); |
| 236 | extern void nfs4_kill_renewd(struct nfs4_client *); | 187 | extern void nfs4_kill_renewd(struct nfs_client *); |
| 237 | extern void nfs4_renew_state(void *); | 188 | extern void nfs4_renew_state(void *); |
| 238 | 189 | ||
| 239 | /* nfs4state.c */ | 190 | /* nfs4state.c */ |
| 240 | extern void init_nfsv4_state(struct nfs_server *); | 191 | struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp); |
| 241 | extern void destroy_nfsv4_state(struct nfs_server *); | 192 | extern u32 nfs4_alloc_lockowner_id(struct nfs_client *); |
| 242 | extern struct nfs4_client *nfs4_get_client(struct in_addr *); | ||
| 243 | extern void nfs4_put_client(struct nfs4_client *clp); | ||
| 244 | extern struct nfs4_client *nfs4_find_client(struct in_addr *); | ||
| 245 | struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp); | ||
| 246 | extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *); | ||
| 247 | 193 | ||
| 248 | extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *); | 194 | extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *); |
| 249 | extern void nfs4_put_state_owner(struct nfs4_state_owner *); | 195 | extern void nfs4_put_state_owner(struct nfs4_state_owner *); |
| @@ -252,7 +198,7 @@ extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state · 2 unmodified lines | |||
| 252 | extern void nfs4_put_open_state(struct nfs4_state *); | 198 | extern void nfs4_put_open_state(struct nfs4_state *); |
| 253 | extern void nfs4_close_state(struct nfs4_state *, mode_t); | 199 | extern void nfs4_close_state(struct nfs4_state *, mode_t); |
| 254 | extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t); | 200 | extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t); |
| 255 | extern void nfs4_schedule_state_recovery(struct nfs4_client *); | 201 | extern void nfs4_schedule_state_recovery(struct nfs_client *); |
| 256 | extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); | 202 | extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); |
| 257 | extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); | 203 | extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); |
| 258 | extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t); | 204 | extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t); |
| @@ -276,10 +222,6 @@ extern struct svc_version nfs4_callback_version1; · 17 unmodified lines | |||
| 276 | 222 | ||
| 277 | #else | 223 | #else |
| 278 | 224 | ||
| 279 | #define init_nfsv4_state(server) do { } while (0) | ||
| 280 | #define destroy_nfsv4_state(server) do { } while (0) | ||
| 281 | #define nfs4_put_state_owner(inode, owner) do { } while (0) | ||
| 282 | #define nfs4_put_open_state(state) do { } while (0) | ||
| 283 | #define nfs4_close_state(a, b) do { } while (0) | 225 | #define nfs4_close_state(a, b) do { } while (0) |
| 284 | 226 | ||
| 285 | #endif /* CONFIG_NFS_V4 */ | 227 | #endif /* CONFIG_NFS_V4 */ |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | * linux/fs/nfs/nfs4namespace.c | 2 | * linux/fs/nfs/nfs4namespace.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com> | 4 | * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com> |
| 5 | * - Modified by David Howells <dhowells@redhat.com> | ||
| 5 | * | 6 | * |
| 6 | * NFSv4 namespace | 7 | * NFSv4 namespace |
| 7 | */ | 8 | */ |
| @@ -23,7 +24,7 @@ · 15 unmodified lines | |||
| 23 | /* | 24 | /* |
| 24 | * Check if fs_root is valid | 25 | * Check if fs_root is valid |
| 25 | */ | 26 | */ |
| 26 | static inline char *nfs4_pathname_string(struct nfs4_pathname *pathname, | 27 | static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname, |
| 27 | char *buffer, ssize_t buflen) | 28 | char *buffer, ssize_t buflen) |
| 28 | { | 29 | { |
| 29 | char *end = buffer + buflen; | 30 | char *end = buffer + buflen; |
| @@ -34,7 +35,7 @@ static inline char *nfs4_pathname_string(struct nfs4_pathname *pathname, · 4 unmodified lines | |||
| 34 | 35 | ||
| 35 | n = pathname->ncomponents; | 36 | n = pathname->ncomponents; |
| 36 | while (--n >= 0) { | 37 | while (--n >= 0) { |
| 37 | struct nfs4_string *component = &pathname->components[n]; | 38 | const struct nfs4_string *component = &pathname->components[n]; |
| 38 | buflen -= component->len + 1; | 39 | buflen -= component->len + 1; |
| 39 | if (buflen < 0) | 40 | if (buflen < 0) |
| 40 | goto Elong; | 41 | goto Elong; |
| @@ -47,6 +48,68 @@ Elong: · 6 unmodified lines | |||
| 47 | return ERR_PTR(-ENAMETOOLONG); | 48 | return ERR_PTR(-ENAMETOOLONG); |
| 48 | } | 49 | } |
| 49 | 50 | ||
| 51 | /* | ||
| 52 | * Determine the mount path as a string | ||
| 53 | */ | ||
| 54 | static char *nfs4_path(const struct vfsmount *mnt_parent, | ||
| 55 | const struct dentry *dentry, | ||
| 56 | char *buffer, ssize_t buflen) | ||
| 57 | { | ||
| 58 | const char *srvpath; | ||
| 59 | |||
| 60 | srvpath = strchr(mnt_parent->mnt_devname, ':'); | ||
| 61 | if (srvpath) | ||
| 62 | srvpath++; | ||
| 63 | else | ||
| 64 | srvpath = mnt_parent->mnt_devname; | ||
| 65 | |||
| 66 | return nfs_path(srvpath, mnt_parent->mnt_root, dentry, buffer, buflen); | ||
| 67 | } | ||
| 68 | |||
| 69 | /* | ||
| 70 | * Check that fs_locations::fs_root [RFC3530 6.3] is a prefix for what we | ||
| 71 | * believe to be the server path to this dentry | ||
| 72 | */ | ||
| 73 | static int nfs4_validate_fspath(const struct vfsmount *mnt_parent, | ||
| 74 | const struct dentry *dentry, | ||
| 75 | const struct nfs4_fs_locations *locations, | ||
| 76 | char *page, char *page2) | ||
| 77 | { | ||
| 78 | const char *path, *fs_path; | ||
| 79 | |||
| 80 | path = nfs4_path(mnt_parent, dentry, page, PAGE_SIZE); | ||
| 81 | if (IS_ERR(path)) | ||
| 82 | return PTR_ERR(path); | ||
| 83 | |||
| 84 | fs_path = nfs4_pathname_string(&locations->fs_path, page2, PAGE_SIZE); | ||
| 85 | if (IS_ERR(fs_path)) | ||
| 86 | return PTR_ERR(fs_path); | ||
| 87 | |||
| 88 | if (strncmp(path, fs_path, strlen(fs_path)) != 0) { | ||
| 89 | dprintk("%s: path %s does not begin with fsroot %s\n", | ||
| 90 | __FUNCTION__, path, fs_path); | ||
| 91 | return -ENOENT; | ||
| 92 | } | ||
| 93 | |||
| 94 | return 0; | ||
| 95 | } | ||
| 96 | |||
| 97 | /* | ||
| 98 | * Check if the string represents a "valid" IPv4 address | ||
| 99 | */ | ||
| 100 | static inline int valid_ipaddr4(const char *buf) | ||
| 101 | { | ||
| 102 | int rc, count, in[4]; | ||
| 103 | |||
| 104 | rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]); | ||
| 105 | if (rc != 4) | ||
| 106 | return -EINVAL; | ||
| 107 | for (count = 0; count < 4; count++) { | ||
| 108 | if (in[count] > 255) | ||
| 109 | return -EINVAL; | ||
| 110 | } | ||
| 111 | return 0; | ||
| 112 | } | ||
| 50 | 113 | ||
| 51 | /** | 114 | /** |
| 52 | * nfs_follow_referral - set up mountpoint when hitting a referral on moved error | 115 | * nfs_follow_referral - set up mountpoint when hitting a referral on moved error |
| @@ -60,7 +123,7 @@ Elong: · 7 unmodified lines | |||
| 60 | */ | 123 | */ |
| 61 | static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent, | 124 | static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent, |
| 62 | const struct dentry *dentry, | 125 | const struct dentry *dentry, |
| 63 | struct nfs4_fs_locations *locations) | 126 | const struct nfs4_fs_locations *locations) |
| 64 | { | 127 | { |
| 65 | struct vfsmount *mnt = ERR_PTR(-ENOENT); | 128 | struct vfsmount *mnt = ERR_PTR(-ENOENT); |
| 66 | struct nfs_clone_mount mountdata = { | 129 | struct nfs_clone_mount mountdata = { |
| @@ -68,10 +131,9 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent, · 1 unmodified line | |||
| 68 | .dentry = dentry, | 131 | .dentry = dentry, |
| 69 | .authflavor = NFS_SB(mnt_parent->mnt_sb)->client->cl_auth->au_flavor, | 132 | .authflavor = NFS_SB(mnt_parent->mnt_sb)->client->cl_auth->au_flavor, |
| 70 | }; | 133 | }; |
| 71 | char *page, *page2; | 134 | char *page = NULL, *page2 = NULL; |
| 72 | char *path, *fs_path; | ||
| 73 | char *devname; | 135 | char *devname; |
| 74 | int loc, s; | 136 | int loc, s, error; |
| 75 | 137 | ||
| 76 | if (locations == NULL || locations->nlocations <= 0) | 138 | if (locations == NULL || locations->nlocations <= 0) |
| 77 | goto out; | 139 | goto out; |
| @@ -79,36 +141,30 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent, · 1 unmodified line | |||
| 79 | dprintk("%s: referral at %s/%s\n", __FUNCTION__, | 141 | dprintk("%s: referral at %s/%s\n", __FUNCTION__, |
| 80 | dentry->d_parent->d_name.name, dentry->d_name.name); | 142 | dentry->d_parent->d_name.name, dentry->d_name.name); |
| 81 | 143 | ||
| 82 | /* Ensure fs path is a prefix of current dentry path */ | ||
| 83 | page = (char *) __get_free_page(GFP_USER); | 144 | page = (char *) __get_free_page(GFP_USER); |
| 84 | if (page == NULL) | 145 | if (!page) |
| 85 | goto out; | 146 | goto out; |
| 147 | |||
| 86 | page2 = (char *) __get_free_page(GFP_USER); | 148 | page2 = (char *) __get_free_page(GFP_USER); |
| 87 | if (page2 == NULL) | 149 | if (!page2) |
| 88 | goto out; | 150 | goto out; |
| 89 | 151 | ||
| 90 | path = nfs4_path(dentry, page, PAGE_SIZE); | 152 | /* Ensure fs path is a prefix of current dentry path */ |
| 91 | if (IS_ERR(path)) | 153 | error = nfs4_validate_fspath(mnt_parent, dentry, locations, page, page2); |
| 92 | goto out_free; | 154 | if (error < 0) { |
| 93 | 155 | mnt = ERR_PTR(error); | |
| 94 | fs_path = nfs4_pathname_string(&locations->fs_path, page2, PAGE_SIZE); | 156 | goto out; |
| 95 | if (IS_ERR(fs_path)) | ||
| 96 | goto out_free; | ||
| 97 | |||
| 98 | if (strncmp(path, fs_path, strlen(fs_path)) != 0) { | ||
| 99 | dprintk("%s: path %s does not begin with fsroot %s\n", __FUNCTION__, path, fs_path); | ||
| 100 | goto out_free; | ||
| 101 | } | 157 | } |
| 102 | 158 | ||
| 103 | devname = nfs_devname(mnt_parent, dentry, page, PAGE_SIZE); | 159 | devname = nfs_devname(mnt_parent, dentry, page, PAGE_SIZE); |
| 104 | if (IS_ERR(devname)) { | 160 | if (IS_ERR(devname)) { |
| 105 | mnt = (struct vfsmount *)devname; | 161 | mnt = (struct vfsmount *)devname; |
| 106 | goto out_free; | 162 | goto out; |
| 107 | } | 163 | } |
| 108 | 164 | ||
| 109 | loc = 0; | 165 | loc = 0; |
| 110 | while (loc < locations->nlocations && IS_ERR(mnt)) { | 166 | while (loc < locations->nlocations && IS_ERR(mnt)) { |
| 111 | struct nfs4_fs_location *location = &locations->locations[loc]; | 167 | const struct nfs4_fs_location *location = &locations->locations[loc]; |
| 112 | char *mnt_path; | 168 | char *mnt_path; |
| 113 | 169 | ||
| 114 | if (location == NULL || location->nservers <= 0 || | 170 | if (location == NULL || location->nservers <= 0 || |
| @@ -140,7 +196,7 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent, · 25 unmodified lines | |||
| 140 | addr.sin_port = htons(NFS_PORT); | 196 | addr.sin_port = htons(NFS_PORT); |
| 141 | mountdata.addr = &addr; | 197 | mountdata.addr = &addr; |
| 142 | 198 | ||
| 143 | mnt = vfs_kern_mount(&nfs_referral_nfs4_fs_type, 0, devname, &mountdata); | 199 | mnt = vfs_kern_mount(&nfs4_referral_fs_type, 0, devname, &mountdata); |
| 144 | if (!IS_ERR(mnt)) { | 200 | if (!IS_ERR(mnt)) { |
| 145 | break; | 201 | break; |
| 146 | } | 202 | } |
| @@ -149,10 +205,9 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent, · 2 unmodified lines | |||
| 149 | loc++; | 205 | loc++; |
| 150 | } | 206 | } |
| 151 | 207 | ||
| 152 | out_free: | ||
| 153 | free_page((unsigned long)page); | ||
| 154 | free_page((unsigned long)page2); | ||
| 155 | out: | 208 | out: |
| 209 | free_page((unsigned long) page); | ||
| 210 | free_page((unsigned long) page2); | ||
| 156 | dprintk("%s: done\n", __FUNCTION__); | 211 | dprintk("%s: done\n", __FUNCTION__); |
| 157 | return mnt; | 212 | return mnt; |
| 158 | } | 213 | } |
| @@ -165,7 +220,7 @@ out: · 6 unmodified lines | |||
| 165 | */ | 220 | */ |
| 166 | struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry) | 221 | struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry) |
| 167 | { | 222 | { |
| 168 | struct vfsmount *mnt = ERR_PTR(-ENOENT); | 223 | struct vfsmount *mnt = ERR_PTR(-ENOMEM); |
| 169 | struct dentry *parent; | 224 | struct dentry *parent; |
| 170 | struct nfs4_fs_locations *fs_locations = NULL; | 225 | struct nfs4_fs_locations *fs_locations = NULL; |
| 171 | struct page *page; | 226 | struct page *page; |
| @@ -183,11 +238,16 @@ struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentr · 11 unmodified lines | |||
| 183 | goto out_free; | 238 | goto out_free; |
| 184 | 239 | ||
| 185 | /* Get locations */ | 240 | /* Get locations */ |
| 241 | mnt = ERR_PTR(-ENOENT); | ||
| 242 | |||
| 186 | parent = dget_parent(dentry); | 243 | parent = dget_parent(dentry); |
| 187 | dprintk("%s: getting locations for %s/%s\n", __FUNCTION__, parent->d_name.name, dentry->d_name.name); | 244 | dprintk("%s: getting locations for %s/%s\n", |
| 245 | __FUNCTION__, parent->d_name.name, dentry->d_name.name); | ||
| 246 | |||
| 188 | err = nfs4_proc_fs_locations(parent->d_inode, dentry, fs_locations, page); | 247 | err = nfs4_proc_fs_locations(parent->d_inode, dentry, fs_locations, page); |
| 189 | dput(parent); | 248 | dput(parent); |
| 190 | if (err != 0 || fs_locations->nlocations <= 0 || | 249 | if (err != 0 || |
| 250 | fs_locations->nlocations <= 0 || | ||
| 191 | fs_locations->fs_path.ncomponents <= 0) | 251 | fs_locations->fs_path.ncomponents <= 0) |
| 192 | goto out_free; | 252 | goto out_free; |
| 193 | 253 | ||
| @@ -55,7 +55,7 @@ · 54 unmodified lines | |||
| 55 | 55 | ||
| 56 | #define NFSDBG_FACILITY NFSDBG_PROC | 56 | #define NFSDBG_FACILITY NFSDBG_PROC |
| 57 | 57 | ||
| 58 | #define NFS4_POLL_RETRY_MIN (1*HZ) | 58 | #define NFS4_POLL_RETRY_MIN (HZ/10) |
| 59 | #define NFS4_POLL_RETRY_MAX (15*HZ) | 59 | #define NFS4_POLL_RETRY_MAX (15*HZ) |
| 60 | 60 | ||
| 61 | struct nfs4_opendata; | 61 | struct nfs4_opendata; |
| @@ -64,7 +64,7 @@ static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinf · 2 unmodified lines | |||
| 64 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); | 64 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); |
| 65 | static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry); | 65 | static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry); |
| 66 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); | 66 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); |
| 67 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp); | 67 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp); |
| 68 | 68 | ||
| 69 | /* Prevent leaks of NFSv4 errors into userland */ | 69 | /* Prevent leaks of NFSv4 errors into userland */ |
| 70 | int nfs4_map_errors(int err) | 70 | int nfs4_map_errors(int err) |
| @@ -195,7 +195,7 @@ static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry, · 124 unmodified lines | |||
| 195 | 195 | ||
| 196 | static void renew_lease(const struct nfs_server *server, unsigned long timestamp) | 196 | static void renew_lease(const struct nfs_server *server, unsigned long timestamp) |
| 197 | { | 197 | { |
| 198 | struct nfs4_client *clp = server->nfs4_state; | 198 | struct nfs_client *clp = server->nfs_client; |
| 199 | spin_lock(&clp->cl_lock); | 199 | spin_lock(&clp->cl_lock); |
| 200 | if (time_before(clp->cl_last_renewal,timestamp)) | 200 | if (time_before(clp->cl_last_renewal,timestamp)) |
| 201 | clp->cl_last_renewal = timestamp; | 201 | clp->cl_last_renewal = timestamp; |
| @@ -252,7 +252,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, · 50 unmodified lines | |||
| 252 | atomic_inc(&sp->so_count); | 252 | atomic_inc(&sp->so_count); |
| 253 | p->o_arg.fh = NFS_FH(dir); | 253 | p->o_arg.fh = NFS_FH(dir); |
| 254 | p->o_arg.open_flags = flags, | 254 | p->o_arg.open_flags = flags, |
| 255 | p->o_arg.clientid = server->nfs4_state->cl_clientid; | 255 | p->o_arg.clientid = server->nfs_client->cl_clientid; |
| 256 | p->o_arg.id = sp->so_id; | 256 | p->o_arg.id = sp->so_id; |
| 257 | p->o_arg.name = &dentry->d_name; | 257 | p->o_arg.name = &dentry->d_name; |
| 258 | p->o_arg.server = server; | 258 | p->o_arg.server = server; |
| @@ -550,7 +550,7 @@ int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state) · 291 unmodified lines | |||
| 550 | case -NFS4ERR_STALE_STATEID: | 550 | case -NFS4ERR_STALE_STATEID: |
| 551 | case -NFS4ERR_EXPIRED: | 551 | case -NFS4ERR_EXPIRED: |
| 552 | /* Don't recall a delegation if it was lost */ | 552 | /* Don't recall a delegation if it was lost */ |
| 553 | nfs4_schedule_state_recovery(server->nfs4_state); | 553 | nfs4_schedule_state_recovery(server->nfs_client); |
| 554 | return err; | 554 | return err; |
| 555 | } | 555 | } |
| 556 | err = nfs4_handle_exception(server, err, &exception); | 556 | err = nfs4_handle_exception(server, err, &exception); |
| @@ -758,7 +758,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) · 201 unmodified lines | |||
| 758 | } | 758 | } |
| 759 | nfs_confirm_seqid(&data->owner->so_seqid, 0); | 759 | nfs_confirm_seqid(&data->owner->so_seqid, 0); |
| 760 | if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) | 760 | if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) |
| 761 | return server->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr); | 761 | return server->nfs_client->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr); |
| 762 | return 0; | 762 | return 0; |
| 763 | } | 763 | } |
| 764 | 764 | ||
| @@ -792,11 +792,18 @@ out: · 27 unmodified lines | |||
| 792 | 792 | ||
| 793 | int nfs4_recover_expired_lease(struct nfs_server *server) | 793 | int nfs4_recover_expired_lease(struct nfs_server *server) |
| 794 | { | 794 | { |
| 795 | struct nfs4_client *clp = server->nfs4_state; | 795 | struct nfs_client *clp = server->nfs_client; |
| 796 | int ret; | ||
| 796 | 797 | ||
| 797 | if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) | 798 | for (;;) { |
| 799 | ret = nfs4_wait_clnt_recover(server->client, clp); | ||
| 800 | if (ret != 0) | ||
| 801 | return ret; | ||
| 802 | if (!test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) | ||
| 803 | break; | ||
| 798 | nfs4_schedule_state_recovery(clp); | 804 | nfs4_schedule_state_recovery(clp); |
| 799 | return nfs4_wait_clnt_recover(server->client, clp); | 805 | } |
| 806 | return 0; | ||
| 800 | } | 807 | } |
| 801 | 808 | ||
| 802 | /* | 809 | /* |
| @@ -867,7 +874,7 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred · 64 unmodified lines | |||
| 867 | { | 874 | { |
| 868 | struct nfs_delegation *delegation; | 875 | struct nfs_delegation *delegation; |
| 869 | struct nfs_server *server = NFS_SERVER(inode); | 876 | struct nfs_server *server = NFS_SERVER(inode); |
| 870 | struct nfs4_client *clp = server->nfs4_state; | 877 | struct nfs_client *clp = server->nfs_client; |
| 871 | struct nfs_inode *nfsi = NFS_I(inode); | 878 | struct nfs_inode *nfsi = NFS_I(inode); |
| 872 | struct nfs4_state_owner *sp = NULL; | 879 | struct nfs4_state_owner *sp = NULL; |
| 873 | struct nfs4_state *state = NULL; | 880 | struct nfs4_state *state = NULL; |
| @@ -953,7 +960,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st · 79 unmodified lines | |||
| 953 | struct nfs4_state_owner *sp; | 960 | struct nfs4_state_owner *sp; |
| 954 | struct nfs4_state *state = NULL; | 961 | struct nfs4_state *state = NULL; |
| 955 | struct nfs_server *server = NFS_SERVER(dir); | 962 | struct nfs_server *server = NFS_SERVER(dir); |
| 956 | struct nfs4_client *clp = server->nfs4_state; | 963 | struct nfs_client *clp = server->nfs_client; |
| 957 | struct nfs4_opendata *opendata; | 964 | struct nfs4_opendata *opendata; |
| 958 | int status; | 965 | int status; |
| 959 | 966 | ||
| @@ -1133,7 +1140,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data) · 173 unmodified lines | |||
| 1133 | break; | 1140 | break; |
| 1134 | case -NFS4ERR_STALE_STATEID: | 1141 | case -NFS4ERR_STALE_STATEID: |
| 1135 | case -NFS4ERR_EXPIRED: | 1142 | case -NFS4ERR_EXPIRED: |
| 1136 | nfs4_schedule_state_recovery(server->nfs4_state); | 1143 | nfs4_schedule_state_recovery(server->nfs_client); |
| 1137 | break; | 1144 | break; |
| 1138 | default: | 1145 | default: |
| 1139 | if (nfs4_async_handle_error(task, server) == -EAGAIN) { | 1146 | if (nfs4_async_handle_error(task, server) == -EAGAIN) { |
| @@ -1268,7 +1275,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) · 128 unmodified lines | |||
| 1268 | BUG_ON(nd->intent.open.flags & O_CREAT); | 1275 | BUG_ON(nd->intent.open.flags & O_CREAT); |
| 1269 | } | 1276 | } |
| 1270 | 1277 | ||
| 1271 | cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0); | 1278 | cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0); |
| 1272 | if (IS_ERR(cred)) | 1279 | if (IS_ERR(cred)) |
| 1273 | return (struct dentry *)cred; | 1280 | return (struct dentry *)cred; |
| 1274 | state = nfs4_do_open(dir, dentry, nd->intent.open.flags, &attr, cred); | 1281 | state = nfs4_do_open(dir, dentry, nd->intent.open.flags, &attr, cred); |
| @@ -1291,7 +1298,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st · 16 unmodified lines | |||
| 1291 | struct rpc_cred *cred; | 1298 | struct rpc_cred *cred; |
| 1292 | struct nfs4_state *state; | 1299 | struct nfs4_state *state; |
| 1293 | 1300 | ||
| 1294 | cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0); | 1301 | cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0); |
| 1295 | if (IS_ERR(cred)) | 1302 | if (IS_ERR(cred)) |
| 1296 | return PTR_ERR(cred); | 1303 | return PTR_ERR(cred); |
| 1297 | state = nfs4_open_delegated(dentry->d_inode, openflags, cred); | 1304 | state = nfs4_open_delegated(dentry->d_inode, openflags, cred); |
| @@ -1393,70 +1400,19 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, · 95 unmodified lines | |||
| 1393 | return err; | 1400 | return err; |
| 1394 | } | 1401 | } |
| 1395 | 1402 | ||
| 1403 | /* | ||
| 1404 | * get the file handle for the "/" directory on the server | ||
| 1405 | */ | ||
| 1396 | static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, | 1406 | static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, |
| 1397 | struct nfs_fsinfo *info) | 1407 | struct nfs_fsinfo *info) |
| 1398 | { | 1408 | { |
| 1399 | struct nfs_fattr * fattr = info->fattr; | ||
| 1400 | unsigned char * p; | ||
| 1401 | struct qstr q; | ||
| 1402 | struct nfs4_lookup_arg args = { | ||
| 1403 | .dir_fh = fhandle, | ||
| 1404 | .name = &q, | ||
| 1405 | .bitmask = nfs4_fattr_bitmap, | ||
| 1406 | }; | ||
| 1407 | struct nfs4_lookup_res res = { | ||
| 1408 | .server = server, | ||
| 1409 | .fattr = fattr, | ||
| 1410 | .fh = fhandle, | ||
| 1411 | }; | ||
| 1412 | struct rpc_message msg = { | ||
| 1413 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP], | ||
| 1414 | .rpc_argp = &args, | ||
| 1415 | .rpc_resp = &res, | ||
| 1416 | }; | ||
| 1417 | int status; | 1409 | int status; |
| 1418 | 1410 | ||
| 1419 | /* | ||
| 1420 | * Now we do a separate LOOKUP for each component of the mount path. | ||
| 1421 | * The LOOKUPs are done separately so that we can conveniently | ||
| 1422 | * catch an ERR_WRONGSEC if it occurs along the way... | ||
| 1423 | */ | ||
| 1424 | status = nfs4_lookup_root(server, fhandle, info); | 1411 | status = nfs4_lookup_root(server, fhandle, info); |
| 1425 | if (status) | ||
| 1426 | goto out; | ||
| 1427 | |||
| 1428 | p = server->mnt_path; | ||
| 1429 | for (;;) { | ||
| 1430 | struct nfs4_exception exception = { }; | ||
| 1431 | |||
| 1432 | while (*p == '/') | ||
| 1433 | p++; | ||
| 1434 | if (!*p) | ||
| 1435 | break; | ||
| 1436 | q.name = p; | ||
| 1437 | while (*p && (*p != '/')) | ||
| 1438 | p++; | ||
| 1439 | q.len = p - q.name; | ||
| 1440 | |||
| 1441 | do { | ||
| 1442 | nfs_fattr_init(fattr); | ||
| 1443 | status = nfs4_handle_exception(server, | ||
| 1444 | rpc_call_sync(server->client, &msg, 0), | ||
| 1445 | &exception); | ||
| 1446 | } while (exception.retry); | ||
| 1447 | if (status == 0) | ||
| 1448 | continue; | ||
| 1449 | if (status == -ENOENT) { | ||
| 1450 | printk(KERN_NOTICE "NFS: mount path %s does not exist!\n", server->mnt_path); | ||
| 1451 | printk(KERN_NOTICE "NFS: suggestion: try mounting '/' instead.\n"); | ||
| 1452 | } | ||
| 1453 | break; | ||
| 1454 | } | ||
| 1455 | if (status == 0) | 1412 | if (status == 0) |
| 1456 | status = nfs4_server_capabilities(server, fhandle); | 1413 | status = nfs4_server_capabilities(server, fhandle); |
| 1457 | if (status == 0) | 1414 | if (status == 0) |
| 1458 | status = nfs4_do_fsinfo(server, fhandle, info); | 1415 | status = nfs4_do_fsinfo(server, fhandle, info); |
| 1459 | out: | ||
| 1460 | return nfs4_map_errors(status); | 1416 | return nfs4_map_errors(status); |
| 1461 | } | 1417 | } |
| 1462 | 1418 | ||
| @@ -1565,7 +1521,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, · 102 unmodified lines | |||
| 1565 | 1521 | ||
| 1566 | nfs_fattr_init(fattr); | 1522 | nfs_fattr_init(fattr); |
| 1567 | 1523 | ||
| 1568 | cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0); | 1524 | cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); |
| 1569 | if (IS_ERR(cred)) | 1525 | if (IS_ERR(cred)) |
| 1570 | return PTR_ERR(cred); | 1526 | return PTR_ERR(cred); |
| 1571 | 1527 | ||
| @@ -1583,6 +1539,52 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, · 11 unmodified lines | |||
| 1583 | return status; | 1539 | return status; |
| 1584 | } | 1540 | } |
| 1585 | 1541 | ||
| 1542 | static int _nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh, | ||
| 1543 | struct qstr *name, struct nfs_fh *fhandle, | ||
| 1544 | struct nfs_fattr *fattr) | ||
| 1545 | { | ||
| 1546 | int status; | ||
| 1547 | struct nfs4_lookup_arg args = { | ||
| 1548 | .bitmask = server->attr_bitmask, | ||
| 1549 | .dir_fh = dirfh, | ||
| 1550 | .name = name, | ||
| 1551 | }; | ||
| 1552 | struct nfs4_lookup_res res = { | ||
| 1553 | .server = server, | ||
| 1554 | .fattr = fattr, | ||
| 1555 | .fh = fhandle, | ||
| 1556 | }; | ||
| 1557 | struct rpc_message msg = { | ||
| 1558 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP], | ||
| 1559 | .rpc_argp = &args, | ||
| 1560 | .rpc_resp = &res, | ||
| 1561 | }; | ||
| 1562 | |||
| 1563 | nfs_fattr_init(fattr); | ||
| 1564 | |||
| 1565 | dprintk("NFS call lookupfh %s\n", name->name); | ||
| 1566 | status = rpc_call_sync(server->client, &msg, 0); | ||
| 1567 | dprintk("NFS reply lookupfh: %d\n", status); | ||
| 1568 | if (status == -NFS4ERR_MOVED) | ||
| 1569 | status = -EREMOTE; | ||
| 1570 | return status; | ||
| 1571 | } | ||
| 1572 | |||
| 1573 | static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh, | ||
| 1574 | struct qstr *name, struct nfs_fh *fhandle, | ||
| 1575 | struct nfs_fattr *fattr) | ||
| 1576 | { | ||
| 1577 | struct nfs4_exception exception = { }; | ||
| 1578 | int err; | ||
| 1579 | do { | ||
| 1580 | err = nfs4_handle_exception(server, | ||
| 1581 | _nfs4_proc_lookupfh(server, dirfh, name, | ||
| 1582 | fhandle, fattr), | ||
| 1583 | &exception); | ||
| 1584 | } while (exception.retry); | ||
| 1585 | return err; | ||
| 1586 | } | ||
| 1587 | |||
| 1586 | static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name, | 1588 | static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name, |
| 1587 | struct nfs_fh *fhandle, struct nfs_fattr *fattr) | 1589 | struct nfs_fh *fhandle, struct nfs_fattr *fattr) |
| 1588 | { | 1590 | { |
| @@ -1881,7 +1883,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, · 292 unmodified lines | |||
| 1881 | struct rpc_cred *cred; | 1883 | struct rpc_cred *cred; |
| 1882 | int status = 0; | 1884 | int status = 0; |
| 1883 | 1885 | ||
| 1884 | cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0); | 1886 | cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0); |
| 1885 | if (IS_ERR(cred)) { | 1887 | if (IS_ERR(cred)) { |
| 1886 | status = PTR_ERR(cred); | 1888 | status = PTR_ERR(cred); |
| 1887 | goto out; | 1889 | goto out; |
| @@ -2089,24 +2091,24 @@ static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *n · 201 unmodified lines | |||
| 2089 | return err; | 2091 | return err; |
| 2090 | } | 2092 | } |
| 2091 | 2093 | ||
| 2092 | static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name, | 2094 | static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, |
| 2093 | struct qstr *path, struct iattr *sattr, struct nfs_fh *fhandle, | 2095 | struct page *page, unsigned int len, struct iattr *sattr) |
| 2094 | struct nfs_fattr *fattr) | ||
| 2095 | { | 2096 | { |
| 2096 | struct nfs_server *server = NFS_SERVER(dir); | 2097 | struct nfs_server *server = NFS_SERVER(dir); |
| 2097 | struct nfs_fattr dir_fattr; | 2098 | struct nfs_fh fhandle; |
| 2099 | struct nfs_fattr fattr, dir_fattr; | ||
| 2098 | struct nfs4_create_arg arg = { | 2100 | struct nfs4_create_arg arg = { |
| 2099 | .dir_fh = NFS_FH(dir), | 2101 | .dir_fh = NFS_FH(dir), |
| 2100 | .server = server, | 2102 | .server = server, |
| 2101 | .name = name, | 2103 | .name = &dentry->d_name, |
| 2102 | .attrs = sattr, | 2104 | .attrs = sattr, |
| 2103 | .ftype = NF4LNK, | 2105 | .ftype = NF4LNK, |
| 2104 | .bitmask = server->attr_bitmask, | 2106 | .bitmask = server->attr_bitmask, |
| 2105 | }; | 2107 | }; |
| 2106 | struct nfs4_create_res res = { | 2108 | struct nfs4_create_res res = { |
| 2107 | .server = server, | 2109 | .server = server, |
| 2108 | .fh = fhandle, | 2110 | .fh = &fhandle, |
| 2109 | .fattr = fattr, | 2111 | .fattr = &fattr, |
| 2110 | .dir_fattr = &dir_fattr, | 2112 | .dir_fattr = &dir_fattr, |
| 2111 | }; | 2113 | }; |
| 2112 | struct rpc_message msg = { | 2114 | struct rpc_message msg = { |
| @@ -2116,29 +2118,32 @@ static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name, · 3 unmodified lines | |||
| 2116 | }; | 2118 | }; |
| 2117 | int status; | 2119 | int status; |
| 2118 | 2120 | ||
| 2119 | if (path->len > NFS4_MAXPATHLEN) | 2121 | if (len > NFS4_MAXPATHLEN) |
| 2120 | return -ENAMETOOLONG; | 2122 | return -ENAMETOOLONG; |
| 2121 | arg.u.symlink = path; | 2123 | |
| 2122 | nfs_fattr_init(fattr); | 2124 | arg.u.symlink.pages = &page; |
| 2125 | arg.u.symlink.len = len; | ||
| 2126 | nfs_fattr_init(&fattr); | ||
| 2123 | nfs_fattr_init(&dir_fattr); | 2127 | nfs_fattr_init(&dir_fattr); |
| 2124 | 2128 | ||
| 2125 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 2129 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
| 2126 | if (!status) | 2130 | if (!status) { |
| 2127 | update_changeattr(dir, &res.dir_cinfo); | 2131 | update_changeattr(dir, &res.dir_cinfo); |
| 2128 | nfs_post_op_update_inode(dir, res.dir_fattr); | 2132 | nfs_post_op_update_inode(dir, res.dir_fattr); |
| 2133 | status = nfs_instantiate(dentry, &fhandle, &fattr); | ||
| 2134 | } | ||
| 2129 | return status; | 2135 | return status; |
| 2130 | } | 2136 | } |
| 2131 | 2137 | ||
| 2132 | static int nfs4_proc_symlink(struct inode *dir, struct qstr *name, | 2138 | static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, |
| 2133 | struct qstr *path, struct iattr *sattr, struct nfs_fh *fhandle, | 2139 | struct page *page, unsigned int len, struct iattr *sattr) |
| 2134 | struct nfs_fattr *fattr) | ||
| 2135 | { | 2140 | { |
| 2136 | struct nfs4_exception exception = { }; | 2141 | struct nfs4_exception exception = { }; |
| 2137 | int err; | 2142 | int err; |
| 2138 | do { | 2143 | do { |
| 2139 | err = nfs4_handle_exception(NFS_SERVER(dir), | 2144 | err = nfs4_handle_exception(NFS_SERVER(dir), |
| 2140 | _nfs4_proc_symlink(dir, name, path, sattr, | 2145 | _nfs4_proc_symlink(dir, dentry, page, |
| 2141 | fhandle, fattr), | 2146 | len, sattr), |
| 2142 | &exception); | 2147 | &exception); |
| 2143 | } while (exception.retry); | 2148 | } while (exception.retry); |
| 2144 | return err; | 2149 | return err; |
| @@ -2521,7 +2526,7 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, int how) · 376 unmodified lines | |||
| 2521 | */ | 2526 | */ |
| 2522 | static void nfs4_renew_done(struct rpc_task *task, void *data) | 2527 | static void nfs4_renew_done(struct rpc_task *task, void *data) |
| 2523 | { | 2528 | { |
| 2524 | struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp; | 2529 | struct nfs_client *clp = (struct nfs_client *)task->tk_msg.rpc_argp; |
| 2525 | unsigned long timestamp = (unsigned long)data; | 2530 | unsigned long timestamp = (unsigned long)data; |
| 2526 | 2531 | ||
| 2527 | if (task->tk_status < 0) { | 2532 | if (task->tk_status < 0) { |
| @@ -2543,7 +2548,7 @@ static const struct rpc_call_ops nfs4_renew_ops = { · 15 unmodified lines | |||
| 2543 | .rpc_call_done = nfs4_renew_done, | 2548 | .rpc_call_done = nfs4_renew_done, |
| 2544 | }; | 2549 | }; |
| 2545 | 2550 | ||
| 2546 | int nfs4_proc_async_renew(struct nfs4_client *clp, struct rpc_cred *cred) | 2551 | int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred) |
| 2547 | { | 2552 | { |
| 2548 | struct rpc_message msg = { | 2553 | struct rpc_message msg = { |
| 2549 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], | 2554 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], |
| @@ -2555,7 +2560,7 @@ int nfs4_proc_async_renew(struct nfs4_client *clp, struct rpc_cred *cred) · 5 unmodified lines | |||
| 2555 | &nfs4_renew_ops, (void *)jiffies); | 2560 | &nfs4_renew_ops, (void *)jiffies); |
| 2556 | } | 2561 | } |
| 2557 | 2562 | ||
| 2558 | int nfs4_proc_renew(struct nfs4_client *clp, struct rpc_cred *cred) | 2563 | int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred) |
| 2559 | { | 2564 | { |
| 2560 | struct rpc_message msg = { | 2565 | struct rpc_message msg = { |
| 2561 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], | 2566 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], |
| @@ -2770,7 +2775,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl · 208 unmodified lines | |||
| 2770 | return -EOPNOTSUPP; | 2775 | return -EOPNOTSUPP; |
| 2771 | nfs_inode_return_delegation(inode); | 2776 | nfs_inode_return_delegation(inode); |
| 2772 | buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); | 2777 | buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); |
| 2773 | ret = rpc_call_sync(NFS_SERVER(inode)->client, &msg, 0); | 2778 | ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); |
| 2774 | if (ret == 0) | 2779 | if (ret == 0) |
| 2775 | nfs4_write_cached_acl(inode, buf, buflen); | 2780 | nfs4_write_cached_acl(inode, buf, buflen); |
| 2776 | return ret; | 2781 | return ret; |
| @@ -2791,7 +2796,7 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen · 14 unmodified lines | |||
| 2791 | static int | 2796 | static int |
| 2792 | nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) | 2797 | nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) |
| 2793 | { | 2798 | { |
| 2794 | struct nfs4_client *clp = server->nfs4_state; | 2799 | struct nfs_client *clp = server->nfs_client; |
| 2795 | 2800 | ||
| 2796 | if (!clp || task->tk_status >= 0) | 2801 | if (!clp || task->tk_status >= 0) |
| 2797 | return 0; | 2802 | return 0; |
| @@ -2828,7 +2833,7 @@ static int nfs4_wait_bit_interruptible(void *word) · 30 unmodified lines | |||
| 2828 | return 0; | 2833 | return 0; |
| 2829 | } | 2834 | } |
| 2830 | 2835 | ||
| 2831 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp) | 2836 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp) |
| 2832 | { | 2837 | { |
| 2833 | sigset_t oldset; | 2838 | sigset_t oldset; |
| 2834 | int res; | 2839 | int res; |
| @@ -2871,7 +2876,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout) · 36 unmodified lines | |||
| 2871 | */ | 2876 | */ |
| 2872 | int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception) | 2877 | int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception) |
| 2873 | { | 2878 | { |
| 2874 | struct nfs4_client *clp = server->nfs4_state; | 2879 | struct nfs_client *clp = server->nfs_client; |
| 2875 | int ret = errorcode; | 2880 | int ret = errorcode; |
| 2876 | 2881 | ||
| 2877 | exception->retry = 0; | 2882 | exception->retry = 0; |
| @@ -2886,6 +2891,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct · 8 unmodified lines | |||
| 2886 | if (ret == 0) | 2891 | if (ret == 0) |
| 2887 | exception->retry = 1; | 2892 | exception->retry = 1; |
| 2888 | break; | 2893 | break; |
| 2894 | case -NFS4ERR_FILE_OPEN: | ||
| 2889 | case -NFS4ERR_GRACE: | 2895 | case -NFS4ERR_GRACE: |
| 2890 | case -NFS4ERR_DELAY: | 2896 | case -NFS4ERR_DELAY: |
| 2891 | ret = nfs4_delay(server->client, &exception->timeout); | 2897 | ret = nfs4_delay(server->client, &exception->timeout); |
| @@ -2898,7 +2904,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct · 6 unmodified lines | |||
| 2898 | return nfs4_map_errors(ret); | 2904 | return nfs4_map_errors(ret); |
| 2899 | } | 2905 | } |
| 2900 | 2906 | ||
| 2901 | int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) | 2907 | int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) |
| 2902 | { | 2908 | { |
| 2903 | nfs4_verifier sc_verifier; | 2909 | nfs4_verifier sc_verifier; |
| 2904 | struct nfs4_setclientid setclientid = { | 2910 | struct nfs4_setclientid setclientid = { |
| @@ -2922,7 +2928,7 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p · 17 unmodified lines | |||
| 2922 | for(;;) { | 2928 | for(;;) { |
| 2923 | setclientid.sc_name_len = scnprintf(setclientid.sc_name, | 2929 | setclientid.sc_name_len = scnprintf(setclientid.sc_name, |
| 2924 | sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u", | 2930 | sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u", |
| 2925 | clp->cl_ipaddr, NIPQUAD(clp->cl_addr.s_addr), | 2931 | clp->cl_ipaddr, NIPQUAD(clp->cl_addr.sin_addr), |
| 2926 | cred->cr_ops->cr_name, | 2932 | cred->cr_ops->cr_name, |
| 2927 | clp->cl_id_uniquifier); | 2933 | clp->cl_id_uniquifier); |
| 2928 | setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, | 2934 | setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, |
| @@ -2945,7 +2951,7 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p · 16 unmodified lines | |||
| 2945 | return status; | 2951 | return status; |
| 2946 | } | 2952 | } |
| 2947 | 2953 | ||
| 2948 | static int _nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cred *cred) | 2954 | static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred) |
| 2949 | { | 2955 | { |
| 2950 | struct nfs_fsinfo fsinfo; | 2956 | struct nfs_fsinfo fsinfo; |
| 2951 | struct rpc_message msg = { | 2957 | struct rpc_message msg = { |
| @@ -2969,7 +2975,7 @@ static int _nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cr · 17 unmodified lines | |||
| 2969 | return status; | 2975 | return status; |
| 2970 | } | 2976 | } |
| 2971 | 2977 | ||
| 2972 | int nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cred *cred) | 2978 | int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred) |
| 2973 | { | 2979 | { |
| 2974 | long timeout; | 2980 | long timeout; |
| 2975 | int err; | 2981 | int err; |
| @@ -3077,7 +3083,7 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4 · 101 unmodified lines | |||
| 3077 | switch (err) { | 3083 | switch (err) { |
| 3078 | case -NFS4ERR_STALE_STATEID: | 3084 | case -NFS4ERR_STALE_STATEID: |
| 3079 | case -NFS4ERR_EXPIRED: | 3085 | case -NFS4ERR_EXPIRED: |
| 3080 | nfs4_schedule_state_recovery(server->nfs4_state); | 3086 | nfs4_schedule_state_recovery(server->nfs_client); |
| 3081 | case 0: | 3087 | case 0: |
| 3082 | return 0; | 3088 | return 0; |
| 3083 | } | 3089 | } |
| @@ -3106,7 +3112,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock · 22 unmodified lines | |||
| 3106 | { | 3112 | { |
| 3107 | struct inode *inode = state->inode; | 3113 | struct inode *inode = state->inode; |
| 3108 | struct nfs_server *server = NFS_SERVER(inode); | 3114 | struct nfs_server *server = NFS_SERVER(inode); |
| 3109 | struct nfs4_client *clp = server->nfs4_state; | 3115 | struct nfs_client *clp = server->nfs_client; |
| 3110 | struct nfs_lockt_args arg = { | 3116 | struct nfs_lockt_args arg = { |
| 3111 | .fh = NFS_FH(inode), | 3117 | .fh = NFS_FH(inode), |
| 3112 | .fl = request, | 3118 | .fl = request, |
| @@ -3231,7 +3237,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data) · 118 unmodified lines | |||
| 3231 | break; | 3237 | break; |
| 3232 | case -NFS4ERR_STALE_STATEID: | 3238 | case -NFS4ERR_STALE_STATEID: |
| 3233 | case -NFS4ERR_EXPIRED: | 3239 | case -NFS4ERR_EXPIRED: |
| 3234 | nfs4_schedule_state_recovery(calldata->server->nfs4_state); | 3240 | nfs4_schedule_state_recovery(calldata->server->nfs_client); |
| 3235 | break; | 3241 | break; |
| 3236 | default: | 3242 | default: |
| 3237 | if (nfs4_async_handle_error(task, calldata->server) == -EAGAIN) { | 3243 | if (nfs4_async_handle_error(task, calldata->server) == -EAGAIN) { |
| @@ -3343,7 +3349,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, · 105 unmodified lines | |||
| 3343 | if (p->arg.lock_seqid == NULL) | 3349 | if (p->arg.lock_seqid == NULL) |
| 3344 | goto out_free; | 3350 | goto out_free; |
| 3345 | p->arg.lock_stateid = &lsp->ls_stateid; | 3351 | p->arg.lock_stateid = &lsp->ls_stateid; |
| 3346 | p->arg.lock_owner.clientid = server->nfs4_state->cl_clientid; | 3352 | p->arg.lock_owner.clientid = server->nfs_client->cl_clientid; |
| 3347 | p->arg.lock_owner.id = lsp->ls_id; | 3353 | p->arg.lock_owner.id = lsp->ls_id; |
| 3348 | p->lsp = lsp; | 3354 | p->lsp = lsp; |
| 3349 | atomic_inc(&lsp->ls_count); | 3355 | atomic_inc(&lsp->ls_count); |
| @@ -3513,7 +3519,7 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request · 163 unmodified lines | |||
| 3513 | 3519 | ||
| 3514 | static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) | 3520 | static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) |
| 3515 | { | 3521 | { |
| 3516 | struct nfs4_client *clp = state->owner->so_client; | 3522 | struct nfs_client *clp = state->owner->so_client; |
| 3517 | unsigned char fl_flags = request->fl_flags; | 3523 | unsigned char fl_flags = request->fl_flags; |
| 3518 | int status; | 3524 | int status; |
| 3519 | 3525 | ||
| @@ -3715,7 +3721,7 @@ static struct inode_operations nfs4_file_inode_operations = { · 195 unmodified lines | |||
| 3715 | .listxattr = nfs4_listxattr, | 3721 | .listxattr = nfs4_listxattr, |
| 3716 | }; | 3722 | }; |
| 3717 | 3723 | ||
| 3718 | struct nfs_rpc_ops nfs_v4_clientops = { | 3724 | const struct nfs_rpc_ops nfs_v4_clientops = { |
| 3719 | .version = 4, /* protocol version */ | 3725 | .version = 4, /* protocol version */ |
| 3720 | .dentry_ops = &nfs4_dentry_operations, | 3726 | .dentry_ops = &nfs4_dentry_operations, |
| 3721 | .dir_inode_ops = &nfs4_dir_inode_operations, | 3727 | .dir_inode_ops = &nfs4_dir_inode_operations, |
| @@ -3723,6 +3729,7 @@ struct nfs_rpc_ops nfs_v4_clientops = { · 1 unmodified line | |||
| 3723 | .getroot = nfs4_proc_get_root, | 3729 | .getroot = nfs4_proc_get_root, |
| 3724 | .getattr = nfs4_proc_getattr, | 3730 | .getattr = nfs4_proc_getattr, |
| 3725 | .setattr = nfs4_proc_setattr, | 3731 | .setattr = nfs4_proc_setattr, |
| 3732 | .lookupfh = nfs4_proc_lookupfh, | ||
| 3726 | .lookup = nfs4_proc_lookup, | 3733 | .lookup = nfs4_proc_lookup, |
| 3727 | .access = nfs4_proc_access, | 3734 | .access = nfs4_proc_access, |
| 3728 | .readlink = nfs4_proc_readlink, | 3735 | .readlink = nfs4_proc_readlink, |
| @@ -3743,6 +3750,7 @@ struct nfs_rpc_ops nfs_v4_clientops = { · 14 unmodified lines | |||
| 3743 | .statfs = nfs4_proc_statfs, | 3750 | .statfs = nfs4_proc_statfs, |
| 3744 | .fsinfo = nfs4_proc_fsinfo, | 3751 | .fsinfo = nfs4_proc_fsinfo, |
| 3745 | .pathconf = nfs4_proc_pathconf, | 3752 | .pathconf = nfs4_proc_pathconf, |
| 3753 | .set_capabilities = nfs4_server_capabilities, | ||
| 3746 | .decode_dirent = nfs4_decode_dirent, | 3754 | .decode_dirent = nfs4_decode_dirent, |
| 3747 | .read_setup = nfs4_proc_read_setup, | 3755 | .read_setup = nfs4_proc_read_setup, |
| 3748 | .read_done = nfs4_read_done, | 3756 | .read_done = nfs4_read_done, |
| @@ -61,7 +61,7 @@ · 60 unmodified lines | |||
| 61 | void | 61 | void |
| 62 | nfs4_renew_state(void *data) | 62 | nfs4_renew_state(void *data) |
| 63 | { | 63 | { |
| 64 | struct nfs4_client *clp = (struct nfs4_client *)data; | 64 | struct nfs_client *clp = (struct nfs_client *)data; |
| 65 | struct rpc_cred *cred; | 65 | struct rpc_cred *cred; |
| 66 | long lease, timeout; | 66 | long lease, timeout; |
| 67 | unsigned long last, now; | 67 | unsigned long last, now; |
| @@ -108,7 +108,7 @@ out: · 40 unmodified lines | |||
| 108 | 108 | ||
| 109 | /* Must be called with clp->cl_sem locked for writes */ | 109 | /* Must be called with clp->cl_sem locked for writes */ |
| 110 | void | 110 | void |
| 111 | nfs4_schedule_state_renewal(struct nfs4_client *clp) | 111 | nfs4_schedule_state_renewal(struct nfs_client *clp) |
| 112 | { | 112 | { |
| 113 | long timeout; | 113 | long timeout; |
| 114 | 114 | ||
| @@ -121,32 +121,20 @@ nfs4_schedule_state_renewal(struct nfs4_client *clp) · 6 unmodified lines | |||
| 121 | __FUNCTION__, (timeout + HZ - 1) / HZ); | 121 | __FUNCTION__, (timeout + HZ - 1) / HZ); |
| 122 | cancel_delayed_work(&clp->cl_renewd); | 122 | cancel_delayed_work(&clp->cl_renewd); |
| 123 | schedule_delayed_work(&clp->cl_renewd, timeout); | 123 | schedule_delayed_work(&clp->cl_renewd, timeout); |
| 124 | set_bit(NFS_CS_RENEWD, &clp->cl_res_state); | ||
| 124 | spin_unlock(&clp->cl_lock); | 125 | spin_unlock(&clp->cl_lock); |
| 125 | } | 126 | } |
| 126 | 127 | ||
| 127 | void | 128 | void |
| 128 | nfs4_renewd_prepare_shutdown(struct nfs_server *server) | 129 | nfs4_renewd_prepare_shutdown(struct nfs_server *server) |
| 129 | { | 130 | { |
| 130 | struct nfs4_client *clp = server->nfs4_state; | ||
| 131 | |||
| 132 | if (!clp) | ||
| 133 | return; | ||
| 134 | flush_scheduled_work(); | 131 | flush_scheduled_work(); |
| 135 | down_write(&clp->cl_sem); | ||
| 136 | if (!list_empty(&server->nfs4_siblings)) | ||
| 137 | list_del_init(&server->nfs4_siblings); | ||
| 138 | up_write(&clp->cl_sem); | ||
| 139 | } | 132 | } |
| 140 | 133 | ||
| 141 | /* Must be called with clp->cl_sem locked for writes */ | ||
| 142 | void | 134 | void |
| 143 | nfs4_kill_renewd(struct nfs4_client *clp) | 135 | nfs4_kill_renewd(struct nfs_client *clp) |
| 144 | { | 136 | { |
| 145 | down_read(&clp->cl_sem); | 137 | down_read(&clp->cl_sem); |
| 146 | if (!list_empty(&clp->cl_superblocks)) { | ||
| 147 | up_read(&clp->cl_sem); | ||
| 148 | return; | ||
| 149 | } | ||
| 150 | cancel_delayed_work(&clp->cl_renewd); | 138 | cancel_delayed_work(&clp->cl_renewd); |
| 151 | up_read(&clp->cl_sem); | 139 | up_read(&clp->cl_sem); |
| 152 | flush_scheduled_work(); | 140 | flush_scheduled_work(); |
| @@ -50,149 +50,15 @@ · 49 unmodified lines | |||
| 50 | #include "nfs4_fs.h" | 50 | #include "nfs4_fs.h" |
| 51 | #include "callback.h" | 51 | #include "callback.h" |
| 52 | #include "delegation.h" | 52 | #include "delegation.h" |
| 53 | #include "internal.h" | ||
| 53 | 54 | ||
| 54 | #define OPENOWNER_POOL_SIZE 8 | 55 | #define OPENOWNER_POOL_SIZE 8 |
| 55 | 56 | ||
| 56 | const nfs4_stateid zero_stateid; | 57 | const nfs4_stateid zero_stateid; |
| 57 | 58 | ||
| 58 | static DEFINE_SPINLOCK(state_spinlock); | ||
| 59 | static LIST_HEAD(nfs4_clientid_list); | 59 | static LIST_HEAD(nfs4_clientid_list); |
| 60 | 60 | ||
| 61 | void | 61 | static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred) |
| 62 | init_nfsv4_state(struct nfs_server *server) | ||
| 63 | { | ||
| 64 | server->nfs4_state = NULL; | ||
| 65 | INIT_LIST_HEAD(&server->nfs4_siblings); | ||
| 66 | } | ||
| 67 | |||
| 68 | void | ||
| 69 | destroy_nfsv4_state(struct nfs_server *server) | ||
| 70 | { | ||
| 71 | kfree(server->mnt_path); | ||
| 72 | server->mnt_path = NULL; | ||
| 73 | if (server->nfs4_state) { | ||
| 74 | nfs4_put_client(server->nfs4_state); | ||
| 75 | server->nfs4_state = NULL; | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | /* | ||
| 80 | * nfs4_get_client(): returns an empty client structure | ||
| 81 | * nfs4_put_client(): drops reference to client structure | ||
| 82 | * | ||
| 83 | * Since these are allocated/deallocated very rarely, we don't | ||
| 84 | * bother putting them in a slab cache... | ||
| 85 | */ | ||
| 86 | static struct nfs4_client * | ||
| 87 | nfs4_alloc_client(struct in_addr *addr) | ||
| 88 | { | ||
| 89 | struct nfs4_client *clp; | ||
| 90 | |||
| 91 | if (nfs_callback_up() < 0) | ||
| 92 | return NULL; | ||
| 93 | if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) { | ||
| 94 | nfs_callback_down(); | ||
| 95 | return NULL; | ||
| 96 | } | ||
| 97 | memcpy(&clp->cl_addr, addr, sizeof(clp->cl_addr)); | ||
| 98 | init_rwsem(&clp->cl_sem); | ||
| 99 | INIT_LIST_HEAD(&clp->cl_delegations); | ||
| 100 | INIT_LIST_HEAD(&clp->cl_state_owners); | ||
| 101 | INIT_LIST_HEAD(&clp->cl_unused); | ||
| 102 | spin_lock_init(&clp->cl_lock); | ||
| 103 | atomic_set(&clp->cl_count, 1); | ||
| 104 | INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); | ||
| 105 | INIT_LIST_HEAD(&clp->cl_superblocks); | ||
| 106 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); | ||
| 107 | clp->cl_rpcclient = ERR_PTR(-EINVAL); | ||
| 108 | clp->cl_boot_time = CURRENT_TIME; | ||
| 109 | clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; | ||
| 110 | return clp; | ||
| 111 | } | ||
| 112 | |||
| 113 | static void | ||
| 114 | nfs4_free_client(struct nfs4_client *clp) | ||
| 115 | { | ||
| 116 | struct nfs4_state_owner *sp; | ||
| 117 | |||
| 118 | while (!list_empty(&clp->cl_unused)) { | ||
| 119 | sp = list_entry(clp->cl_unused.next, | ||
| 120 | struct nfs4_state_owner, | ||
| 121 | so_list); | ||
| 122 | list_del(&sp->so_list); | ||
| 123 | kfree(sp); | ||
| 124 | } | ||
| 125 | BUG_ON(!list_empty(&clp->cl_state_owners)); | ||
| 126 | nfs_idmap_delete(clp); | ||
| 127 | if (!IS_ERR(clp->cl_rpcclient)) | ||
| 128 | rpc_shutdown_client(clp->cl_rpcclient); | ||
| 129 | kfree(clp); | ||
| 130 | nfs_callback_down(); | ||
| 131 | } | ||
| 132 | |||
| 133 | static struct nfs4_client *__nfs4_find_client(struct in_addr *addr) | ||
| 134 | { | ||
| 135 | struct nfs4_client *clp; | ||
| 136 | list_for_each_entry(clp, &nfs4_clientid_list, cl_servers) { | ||
| 137 | if (memcmp(&clp->cl_addr, addr, sizeof(clp->cl_addr)) == 0) { | ||
| 138 | atomic_inc(&clp->cl_count); | ||
| 139 | return clp; | ||
| 140 | } | ||
| 141 | } | ||
| 142 | return NULL; | ||
| 143 | } | ||
| 144 | |||
| 145 | struct nfs4_client *nfs4_find_client(struct in_addr *addr) | ||
| 146 | { | ||
| 147 | struct nfs4_client *clp; | ||
| 148 | spin_lock(&state_spinlock); | ||
| 149 | clp = __nfs4_find_client(addr); | ||
| 150 | spin_unlock(&state_spinlock); | ||
| 151 | return clp; | ||
| 152 | } | ||
| 153 | |||
| 154 | struct nfs4_client * | ||
| 155 | nfs4_get_client(struct in_addr *addr) | ||
| 156 | { | ||
| 157 | struct nfs4_client *clp, *new = NULL; | ||
| 158 | |||
| 159 | spin_lock(&state_spinlock); | ||
| 160 | for (;;) { | ||
| 161 | clp = __nfs4_find_client(addr); | ||
| 162 | if (clp != NULL) | ||
| 163 | break; | ||
| 164 | clp = new; | ||
| 165 | if (clp != NULL) { | ||
| 166 | list_add(&clp->cl_servers, &nfs4_clientid_list); | ||
| 167 | new = NULL; | ||
| 168 | break; | ||
| 169 | } | ||
| 170 | spin_unlock(&state_spinlock); | ||
| 171 | new = nfs4_alloc_client(addr); | ||
| 172 | spin_lock(&state_spinlock); | ||
| 173 | if (new == NULL) | ||
| 174 | break; | ||
| 175 | } | ||
| 176 | spin_unlock(&state_spinlock); | ||
| 177 | if (new) | ||
| 178 | nfs4_free_client(new); | ||
| 179 | return clp; | ||
| 180 | } | ||
| 181 | |||
| 182 | void | ||
| 183 | nfs4_put_client(struct nfs4_client *clp) | ||
| 184 | { | ||
| 185 | if (!atomic_dec_and_lock(&clp->cl_count, &state_spinlock)) | ||
| 186 | return; | ||
| 187 | list_del(&clp->cl_servers); | ||
| 188 | spin_unlock(&state_spinlock); | ||
| 189 | BUG_ON(!list_empty(&clp->cl_superblocks)); | ||
| 190 | rpc_wake_up(&clp->cl_rpcwaitq); | ||
| 191 | nfs4_kill_renewd(clp); | ||
| 192 | nfs4_free_client(clp); | ||
| 193 | } | ||
| 194 | |||
| 195 | static int nfs4_init_client(struct nfs4_client *clp, struct rpc_cred *cred) | ||
| 196 | { | 62 | { |
| 197 | int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, | 63 | int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, |
| 198 | nfs_callback_tcpport, cred); | 64 | nfs_callback_tcpport, cred); |
| @@ -204,13 +70,13 @@ static int nfs4_init_client(struct nfs4_client *clp, struct rpc_cred *cred) · 5 unmodified lines | |||
| 204 | } | 70 | } |
| 205 | 71 | ||
| 206 | u32 | 72 | u32 |
| 207 | nfs4_alloc_lockowner_id(struct nfs4_client *clp) | 73 | nfs4_alloc_lockowner_id(struct nfs_client *clp) |
| 208 | { | 74 | { |
| 209 | return clp->cl_lockowner_id ++; | 75 | return clp->cl_lockowner_id ++; |
| 210 | } | 76 | } |
| 211 | 77 | ||
| 212 | static struct nfs4_state_owner * | 78 | static struct nfs4_state_owner * |
| 213 | nfs4_client_grab_unused(struct nfs4_client *clp, struct rpc_cred *cred) | 79 | nfs4_client_grab_unused(struct nfs_client *clp, struct rpc_cred *cred) |
| 214 | { | 80 | { |
| 215 | struct nfs4_state_owner *sp = NULL; | 81 | struct nfs4_state_owner *sp = NULL; |
| 216 | 82 | ||
| @@ -224,7 +90,7 @@ nfs4_client_grab_unused(struct nfs4_client *clp, struct rpc_cred *cred) · 7 unmodified lines | |||
| 224 | return sp; | 90 | return sp; |
| 225 | } | 91 | } |
| 226 | 92 | ||
| 227 | struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp) | 93 | struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp) |
| 228 | { | 94 | { |
| 229 | struct nfs4_state_owner *sp; | 95 | struct nfs4_state_owner *sp; |
| 230 | struct rpc_cred *cred = NULL; | 96 | struct rpc_cred *cred = NULL; |
| @@ -238,7 +104,7 @@ struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp) · 7 unmodified lines | |||
| 238 | return cred; | 104 | return cred; |
| 239 | } | 105 | } |
| 240 | 106 | ||
| 241 | struct rpc_cred *nfs4_get_setclientid_cred(struct nfs4_client *clp) | 107 | struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp) |
| 242 | { | 108 | { |
| 243 | struct nfs4_state_owner *sp; | 109 | struct nfs4_state_owner *sp; |
| 244 | 110 | ||
| @@ -251,7 +117,7 @@ struct rpc_cred *nfs4_get_setclientid_cred(struct nfs4_client *clp) · 6 unmodified lines | |||
| 251 | } | 117 | } |
| 252 | 118 | ||
| 253 | static struct nfs4_state_owner * | 119 | static struct nfs4_state_owner * |
| 254 | nfs4_find_state_owner(struct nfs4_client *clp, struct rpc_cred *cred) | 120 | nfs4_find_state_owner(struct nfs_client *clp, struct rpc_cred *cred) |
| 255 | { | 121 | { |
| 256 | struct nfs4_state_owner *sp, *res = NULL; | 122 | struct nfs4_state_owner *sp, *res = NULL; |
| 257 | 123 | ||
| @@ -294,7 +160,7 @@ nfs4_alloc_state_owner(void) · 36 unmodified lines | |||
| 294 | void | 160 | void |
| 295 | nfs4_drop_state_owner(struct nfs4_state_owner *sp) | 161 | nfs4_drop_state_owner(struct nfs4_state_owner *sp) |
| 296 | { | 162 | { |
| 297 | struct nfs4_client *clp = sp->so_client; | 163 | struct nfs_client *clp = sp->so_client; |
| 298 | spin_lock(&clp->cl_lock); | 164 | spin_lock(&clp->cl_lock); |
| 299 | list_del_init(&sp->so_list); | 165 | list_del_init(&sp->so_list); |
| 300 | spin_unlock(&clp->cl_lock); | 166 | spin_unlock(&clp->cl_lock); |
| @@ -306,7 +172,7 @@ nfs4_drop_state_owner(struct nfs4_state_owner *sp) · 5 unmodified lines | |||
| 306 | */ | 172 | */ |
| 307 | struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct rpc_cred *cred) | 173 | struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct rpc_cred *cred) |
| 308 | { | 174 | { |
| 309 | struct nfs4_client *clp = server->nfs4_state; | 175 | struct nfs_client *clp = server->nfs_client; |
| 310 | struct nfs4_state_owner *sp, *new; | 176 | struct nfs4_state_owner *sp, *new; |
| 311 | 177 | ||
| 312 | get_rpccred(cred); | 178 | get_rpccred(cred); |
| @@ -337,7 +203,7 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct · 24 unmodified lines | |||
| 337 | */ | 203 | */ |
| 338 | void nfs4_put_state_owner(struct nfs4_state_owner *sp) | 204 | void nfs4_put_state_owner(struct nfs4_state_owner *sp) |
| 339 | { | 205 | { |
| 340 | struct nfs4_client *clp = sp->so_client; | 206 | struct nfs_client *clp = sp->so_client; |
| 341 | struct rpc_cred *cred = sp->so_cred; | 207 | struct rpc_cred *cred = sp->so_cred; |
| 342 | 208 | ||
| 343 | if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock)) | 209 | if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock)) |
| @@ -540,7 +406,7 @@ __nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner) · 196 unmodified lines | |||
| 540 | static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner) | 406 | static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner) |
| 541 | { | 407 | { |
| 542 | struct nfs4_lock_state *lsp; | 408 | struct nfs4_lock_state *lsp; |
| 543 | struct nfs4_client *clp = state->owner->so_client; | 409 | struct nfs_client *clp = state->owner->so_client; |
| 544 | 410 | ||
| 545 | lsp = kzalloc(sizeof(*lsp), GFP_KERNEL); | 411 | lsp = kzalloc(sizeof(*lsp), GFP_KERNEL); |
| 546 | if (lsp == NULL) | 412 | if (lsp == NULL) |
| @@ -752,7 +618,7 @@ out: · 205 unmodified lines | |||
| 752 | 618 | ||
| 753 | static int reclaimer(void *); | 619 | static int reclaimer(void *); |
| 754 | 620 | ||
| 755 | static inline void nfs4_clear_recover_bit(struct nfs4_client *clp) | 621 | static inline void nfs4_clear_recover_bit(struct nfs_client *clp) |
| 756 | { | 622 | { |
| 757 | smp_mb__before_clear_bit(); | 623 | smp_mb__before_clear_bit(); |
| 758 | clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state); | 624 | clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state); |
| @@ -764,25 +630,25 @@ static inline void nfs4_clear_recover_bit(struct nfs4_client *clp) · 5 unmodified lines | |||
| 764 | /* | 630 | /* |
| 765 | * State recovery routine | 631 | * State recovery routine |
| 766 | */ | 632 | */ |
| 767 | static void nfs4_recover_state(struct nfs4_client *clp) | 633 | static void nfs4_recover_state(struct nfs_client *clp) |
| 768 | { | 634 | { |
| 769 | struct task_struct *task; | 635 | struct task_struct *task; |
| 770 | 636 | ||
| 771 | __module_get(THIS_MODULE); | 637 | __module_get(THIS_MODULE); |
| 772 | atomic_inc(&clp->cl_count); | 638 | atomic_inc(&clp->cl_count); |
| 773 | task = kthread_run(reclaimer, clp, "%u.%u.%u.%u-reclaim", | 639 | task = kthread_run(reclaimer, clp, "%u.%u.%u.%u-reclaim", |
| 774 | NIPQUAD(clp->cl_addr)); | 640 | NIPQUAD(clp->cl_addr.sin_addr)); |
| 775 | if (!IS_ERR(task)) | 641 | if (!IS_ERR(task)) |
| 776 | return; | 642 | return; |
| 777 | nfs4_clear_recover_bit(clp); | 643 | nfs4_clear_recover_bit(clp); |
| 778 | nfs4_put_client(clp); | 644 | nfs_put_client(clp); |
| 779 | module_put(THIS_MODULE); | 645 | module_put(THIS_MODULE); |
| 780 | } | 646 | } |
| 781 | 647 | ||
| 782 | /* | 648 | /* |
| 783 | * Schedule a state recovery attempt | 649 | * Schedule a state recovery attempt |
| 784 | */ | 650 | */ |
| 785 | void nfs4_schedule_state_recovery(struct nfs4_client *clp) | 651 | void nfs4_schedule_state_recovery(struct nfs_client *clp) |
| 786 | { | 652 | { |
| 787 | if (!clp) | 653 | if (!clp) |
| 788 | return; | 654 | return; |
| @@ -879,7 +745,7 @@ out_err: · 90 unmodified lines | |||
| 879 | return status; | 745 | return status; |
| 880 | } | 746 | } |
| 881 | 747 | ||
| 882 | static void nfs4_state_mark_reclaim(struct nfs4_client *clp) | 748 | static void nfs4_state_mark_reclaim(struct nfs_client *clp) |
| 883 | { | 749 | { |
| 884 | struct nfs4_state_owner *sp; | 750 | struct nfs4_state_owner *sp; |
| 885 | struct nfs4_state *state; | 751 | struct nfs4_state *state; |
| @@ -903,7 +769,7 @@ static void nfs4_state_mark_reclaim(struct nfs4_client *clp) · 17 unmodified lines | |||
| 903 | 769 | ||
| 904 | static int reclaimer(void *ptr) | 770 | static int reclaimer(void *ptr) |
| 905 | { | 771 | { |
| 906 | struct nfs4_client *clp = ptr; | 772 | struct nfs_client *clp = ptr; |
| 907 | struct nfs4_state_owner *sp; | 773 | struct nfs4_state_owner *sp; |
| 908 | struct nfs4_state_recovery_ops *ops; | 774 | struct nfs4_state_recovery_ops *ops; |
| 909 | struct rpc_cred *cred; | 775 | struct rpc_cred *cred; |
| @@ -970,12 +836,12 @@ out: · 60 unmodified lines | |||
| 970 | if (status == -NFS4ERR_CB_PATH_DOWN) | 836 | if (status == -NFS4ERR_CB_PATH_DOWN) |
| 971 | nfs_handle_cb_pathdown(clp); | 837 | nfs_handle_cb_pathdown(clp); |
| 972 | nfs4_clear_recover_bit(clp); | 838 | nfs4_clear_recover_bit(clp); |
| 973 | nfs4_put_client(clp); | 839 | nfs_put_client(clp); |
| 974 | module_put_and_exit(0); | 840 | module_put_and_exit(0); |
| 975 | return 0; | 841 | return 0; |
| 976 | out_error: | 842 | out_error: |
| 977 | printk(KERN_WARNING "Error: state recovery failed on NFSv4 server %u.%u.%u.%u with error %d\n", | 843 | printk(KERN_WARNING "Error: state recovery failed on NFSv4 server %u.%u.%u.%u with error %d\n", |
| 978 | NIPQUAD(clp->cl_addr.s_addr), -status); | 844 | NIPQUAD(clp->cl_addr.sin_addr), -status); |
| 979 | set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); | 845 | set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); |
| 980 | goto out; | 846 | goto out; |
| 981 | } | 847 | } |
| @@ -58,7 +58,7 @@ · 57 unmodified lines | |||
| 58 | /* Mapping from NFS error code to "errno" error code. */ | 58 | /* Mapping from NFS error code to "errno" error code. */ |
| 59 | #define errno_NFSERR_IO EIO | 59 | #define errno_NFSERR_IO EIO |
| 60 | 60 | ||
| 61 | static int nfs_stat_to_errno(int); | 61 | static int nfs4_stat_to_errno(int); |
| 62 | 62 | ||
| 63 | /* NFSv4 COMPOUND tags are only wanted for debugging purposes */ | 63 | /* NFSv4 COMPOUND tags are only wanted for debugging purposes */ |
| 64 | #ifdef DEBUG | 64 | #ifdef DEBUG |
| @@ -128,7 +128,7 @@ static int nfs_stat_to_errno(int); · 63 unmodified lines | |||
| 128 | #define decode_link_maxsz (op_decode_hdr_maxsz + 5) | 128 | #define decode_link_maxsz (op_decode_hdr_maxsz + 5) |
| 129 | #define encode_symlink_maxsz (op_encode_hdr_maxsz + \ | 129 | #define encode_symlink_maxsz (op_encode_hdr_maxsz + \ |
| 130 | 1 + nfs4_name_maxsz + \ | 130 | 1 + nfs4_name_maxsz + \ |
| 131 | nfs4_path_maxsz + \ | 131 | 1 + \ |
| 132 | nfs4_fattr_maxsz) | 132 | nfs4_fattr_maxsz) |
| 133 | #define decode_symlink_maxsz (op_decode_hdr_maxsz + 8) | 133 | #define decode_symlink_maxsz (op_decode_hdr_maxsz + 8) |
| 134 | #define encode_create_maxsz (op_encode_hdr_maxsz + \ | 134 | #define encode_create_maxsz (op_encode_hdr_maxsz + \ |
| @@ -529,7 +529,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s · 394 unmodified lines | |||
| 529 | if (iap->ia_valid & ATTR_MODE) | 529 | if (iap->ia_valid & ATTR_MODE) |
| 530 | len += 4; | 530 | len += 4; |
| 531 | if (iap->ia_valid & ATTR_UID) { | 531 | if (iap->ia_valid & ATTR_UID) { |
| 532 | owner_namelen = nfs_map_uid_to_name(server->nfs4_state, iap->ia_uid, owner_name); | 532 | owner_namelen = nfs_map_uid_to_name(server->nfs_client, iap->ia_uid, owner_name); |
| 533 | if (owner_namelen < 0) { | 533 | if (owner_namelen < 0) { |
| 534 | printk(KERN_WARNING "nfs: couldn't resolve uid %d to string\n", | 534 | printk(KERN_WARNING "nfs: couldn't resolve uid %d to string\n", |
| 535 | iap->ia_uid); | 535 | iap->ia_uid); |
| @@ -541,7 +541,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s · 5 unmodified lines | |||
| 541 | len += 4 + (XDR_QUADLEN(owner_namelen) << 2); | 541 | len += 4 + (XDR_QUADLEN(owner_namelen) << 2); |
| 542 | } | 542 | } |
| 543 | if (iap->ia_valid & ATTR_GID) { | 543 | if (iap->ia_valid & ATTR_GID) { |
| 544 | owner_grouplen = nfs_map_gid_to_group(server->nfs4_state, iap->ia_gid, owner_group); | 544 | owner_grouplen = nfs_map_gid_to_group(server->nfs_client, iap->ia_gid, owner_group); |
| 545 | if (owner_grouplen < 0) { | 545 | if (owner_grouplen < 0) { |
| 546 | printk(KERN_WARNING "nfs4: couldn't resolve gid %d to string\n", | 546 | printk(KERN_WARNING "nfs4: couldn't resolve gid %d to string\n", |
| 547 | iap->ia_gid); | 547 | iap->ia_gid); |
| @@ -673,9 +673,9 @@ static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *c · 125 unmodified lines | |||
| 673 | 673 | ||
| 674 | switch (create->ftype) { | 674 | switch (create->ftype) { |
| 675 | case NF4LNK: | 675 | case NF4LNK: |
| 676 | RESERVE_SPACE(4 + create->u.symlink->len); | 676 | RESERVE_SPACE(4); |
| 677 | WRITE32(create->u.symlink->len); | 677 | WRITE32(create->u.symlink.len); |
| 678 | WRITEMEM(create->u.symlink->name, create->u.symlink->len); | 678 | xdr_write_pages(xdr, create->u.symlink.pages, 0, create->u.symlink.len); |
| 679 | break; | 679 | break; |
| 680 | 680 | ||
| 681 | case NF4BLK: case NF4CHR: | 681 | case NF4BLK: case NF4CHR: |
| @@ -1160,7 +1160,7 @@ static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, con · 478 unmodified lines | |||
| 1160 | return 0; | 1160 | return 0; |
| 1161 | } | 1161 | } |
| 1162 | 1162 | ||
| 1163 | static int encode_renew(struct xdr_stream *xdr, const struct nfs4_client *client_stateid) | 1163 | static int encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid) |
| 1164 | { | 1164 | { |
| 1165 | uint32_t *p; | 1165 | uint32_t *p; |
| 1166 | 1166 | ||
| @@ -1246,7 +1246,7 @@ static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclien · 79 unmodified lines | |||
| 1246 | return 0; | 1246 | return 0; |
| 1247 | } | 1247 | } |
| 1248 | 1248 | ||
| 1249 | static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_client *client_state) | 1249 | static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state) |
| 1250 | { | 1250 | { |
| 1251 | uint32_t *p; | 1251 | uint32_t *p; |
| 1252 | 1252 | ||
| @@ -1945,7 +1945,7 @@ static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, uint32_t *p, const str · 692 unmodified lines | |||
| 1945 | /* | 1945 | /* |
| 1946 | * a RENEW request | 1946 | * a RENEW request |
| 1947 | */ | 1947 | */ |
| 1948 | static int nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs4_client *clp) | 1948 | static int nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs_client *clp) |
| 1949 | { | 1949 | { |
| 1950 | struct xdr_stream xdr; | 1950 | struct xdr_stream xdr; |
| 1951 | struct compound_hdr hdr = { | 1951 | struct compound_hdr hdr = { |
| @@ -1975,7 +1975,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, uint32_t *p, struct nf · 23 unmodified lines | |||
| 1975 | /* | 1975 | /* |
| 1976 | * a SETCLIENTID_CONFIRM request | 1976 | * a SETCLIENTID_CONFIRM request |
| 1977 | */ | 1977 | */ |
| 1978 | static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs4_client *clp) | 1978 | static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_client *clp) |
| 1979 | { | 1979 | { |
| 1980 | struct xdr_stream xdr; | 1980 | struct xdr_stream xdr; |
| 1981 | struct compound_hdr hdr = { | 1981 | struct compound_hdr hdr = { |
| @@ -2127,12 +2127,12 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) · 145 unmodified lines | |||
| 2127 | } | 2127 | } |
| 2128 | READ32(nfserr); | 2128 | READ32(nfserr); |
| 2129 | if (nfserr != NFS_OK) | 2129 | if (nfserr != NFS_OK) |
| 2130 | return -nfs_stat_to_errno(nfserr); | 2130 | return -nfs4_stat_to_errno(nfserr); |
| 2131 | return 0; | 2131 | return 0; |
| 2132 | } | 2132 | } |
| 2133 | 2133 | ||
| 2134 | /* Dummy routine */ | 2134 | /* Dummy routine */ |
| 2135 | static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs4_client *clp) | 2135 | static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp) |
| 2136 | { | 2136 | { |
| 2137 | uint32_t *p; | 2137 | uint32_t *p; |
| 2138 | unsigned int strlen; | 2138 | unsigned int strlen; |
| @@ -2636,7 +2636,7 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t · 497 unmodified lines | |||
| 2636 | return 0; | 2636 | return 0; |
| 2637 | } | 2637 | } |
| 2638 | 2638 | ||
| 2639 | static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_client *clp, int32_t *uid) | 2639 | static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *uid) |
| 2640 | { | 2640 | { |
| 2641 | uint32_t len, *p; | 2641 | uint32_t len, *p; |
| 2642 | 2642 | ||
| @@ -2660,7 +2660,7 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf · 17 unmodified lines | |||
| 2660 | return 0; | 2660 | return 0; |
| 2661 | } | 2661 | } |
| 2662 | 2662 | ||
| 2663 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_client *clp, int32_t *gid) | 2663 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *gid) |
| 2664 | { | 2664 | { |
| 2665 | uint32_t len, *p; | 2665 | uint32_t len, *p; |
| 2666 | 2666 | ||
| @@ -3051,9 +3051,9 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons · 384 unmodified lines | |||
| 3051 | fattr->mode |= fmode; | 3051 | fattr->mode |= fmode; |
| 3052 | if ((status = decode_attr_nlink(xdr, bitmap, &fattr->nlink)) != 0) | 3052 | if ((status = decode_attr_nlink(xdr, bitmap, &fattr->nlink)) != 0) |
| 3053 | goto xdr_error; | 3053 | goto xdr_error; |
| 3054 | if ((status = decode_attr_owner(xdr, bitmap, server->nfs4_state, &fattr->uid)) != 0) | 3054 | if ((status = decode_attr_owner(xdr, bitmap, server->nfs_client, &fattr->uid)) != 0) |
| 3055 | goto xdr_error; | 3055 | goto xdr_error; |
| 3056 | if ((status = decode_attr_group(xdr, bitmap, server->nfs4_state, &fattr->gid)) != 0) | 3056 | if ((status = decode_attr_group(xdr, bitmap, server->nfs_client, &fattr->gid)) != 0) |
| 3057 | goto xdr_error; | 3057 | goto xdr_error; |
| 3058 | if ((status = decode_attr_rdev(xdr, bitmap, &fattr->rdev)) != 0) | 3058 | if ((status = decode_attr_rdev(xdr, bitmap, &fattr->rdev)) != 0) |
| 3059 | goto xdr_error; | 3059 | goto xdr_error; |
| @@ -3254,7 +3254,7 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) · 194 unmodified lines | |||
| 3254 | if (decode_space_limit(xdr, &res->maxsize) < 0) | 3254 | if (decode_space_limit(xdr, &res->maxsize) < 0) |
| 3255 | return -EIO; | 3255 | return -EIO; |
| 3256 | } | 3256 | } |
| 3257 | return decode_ace(xdr, NULL, res->server->nfs4_state); | 3257 | return decode_ace(xdr, NULL, res->server->nfs_client); |
| 3258 | } | 3258 | } |
| 3259 | 3259 | ||
| 3260 | static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) | 3260 | static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) |
| @@ -3565,7 +3565,7 @@ static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res) · 304 unmodified lines | |||
| 3565 | return 0; | 3565 | return 0; |
| 3566 | } | 3566 | } |
| 3567 | 3567 | ||
| 3568 | static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_client *clp) | 3568 | static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) |
| 3569 | { | 3569 | { |
| 3570 | uint32_t *p; | 3570 | uint32_t *p; |
| 3571 | uint32_t opnum; | 3571 | uint32_t opnum; |
| @@ -3598,7 +3598,7 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_client *clp) · 26 unmodified lines | |||
| 3598 | READ_BUF(len); | 3598 | READ_BUF(len); |
| 3599 | return -NFSERR_CLID_INUSE; | 3599 | return -NFSERR_CLID_INUSE; |
| 3600 | } else | 3600 | } else |
| 3601 | return -nfs_stat_to_errno(nfserr); | 3601 | return -nfs4_stat_to_errno(nfserr); |
| 3602 | 3602 | ||
| 3603 | return 0; | 3603 | return 0; |
| 3604 | } | 3604 | } |
| @@ -4256,7 +4256,7 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs_fsi · 651 unmodified lines | |||
| 4256 | if (!status) | 4256 | if (!status) |
| 4257 | status = decode_fsinfo(&xdr, fsinfo); | 4257 | status = decode_fsinfo(&xdr, fsinfo); |
| 4258 | if (!status) | 4258 | if (!status) |
| 4259 | status = -nfs_stat_to_errno(hdr.status); | 4259 | status = -nfs4_stat_to_errno(hdr.status); |
| 4260 | return status; | 4260 | return status; |
| 4261 | } | 4261 | } |
| 4262 | 4262 | ||
| @@ -4335,7 +4335,7 @@ static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, uint32_t *p, void *dummy) · 72 unmodified lines | |||
| 4335 | * a SETCLIENTID request | 4335 | * a SETCLIENTID request |
| 4336 | */ | 4336 | */ |
| 4337 | static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p, | 4337 | static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p, |
| 4338 | struct nfs4_client *clp) | 4338 | struct nfs_client *clp) |
| 4339 | { | 4339 | { |
| 4340 | struct xdr_stream xdr; | 4340 | struct xdr_stream xdr; |
| 4341 | struct compound_hdr hdr; | 4341 | struct compound_hdr hdr; |
| @@ -4346,7 +4346,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p, · 4 unmodified lines | |||
| 4346 | if (!status) | 4346 | if (!status) |
| 4347 | status = decode_setclientid(&xdr, clp); | 4347 | status = decode_setclientid(&xdr, clp); |
| 4348 | if (!status) | 4348 | if (!status) |
| 4349 | status = -nfs_stat_to_errno(hdr.status); | 4349 | status = -nfs4_stat_to_errno(hdr.status); |
| 4350 | return status; | 4350 | return status; |
| 4351 | } | 4351 | } |
| 4352 | 4352 | ||
| @@ -4368,7 +4368,7 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, s · 15 unmodified lines | |||
| 4368 | if (!status) | 4368 | if (!status) |
| 4369 | status = decode_fsinfo(&xdr, fsinfo); | 4369 | status = decode_fsinfo(&xdr, fsinfo); |
| 4370 | if (!status) | 4370 | if (!status) |
| 4371 | status = -nfs_stat_to_errno(hdr.status); | 4371 | status = -nfs4_stat_to_errno(hdr.status); |
| 4372 | return status; | 4372 | return status; |
| 4373 | } | 4373 | } |
| 4374 | 4374 | ||
| @@ -4521,7 +4521,7 @@ static struct { · 146 unmodified lines | |||
| 4521 | * This one is used jointly by NFSv2 and NFSv3. | 4521 | * This one is used jointly by NFSv2 and NFSv3. |
| 4522 | */ | 4522 | */ |
| 4523 | static int | 4523 | static int |
| 4524 | nfs_stat_to_errno(int stat) | 4524 | nfs4_stat_to_errno(int stat) |
| 4525 | { | 4525 | { |
| 4526 | int i; | 4526 | int i; |
| 4527 | for (i = 0; nfs_errtbl[i].stat != -1; i++) { | 4527 | for (i = 0; nfs_errtbl[i].stat != -1; i++) { |
| @@ -66,14 +66,14 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, · 65 unmodified lines | |||
| 66 | 66 | ||
| 67 | dprintk("%s: call getattr\n", __FUNCTION__); | 67 | dprintk("%s: call getattr\n", __FUNCTION__); |
| 68 | nfs_fattr_init(fattr); | 68 | nfs_fattr_init(fattr); |
| 69 | status = rpc_call_sync(server->client_sys, &msg, 0); | 69 | status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0); |
| 70 | dprintk("%s: reply getattr: %d\n", __FUNCTION__, status); | 70 | dprintk("%s: reply getattr: %d\n", __FUNCTION__, status); |
| 71 | if (status) | 71 | if (status) |
| 72 | return status; | 72 | return status; |
| 73 | dprintk("%s: call statfs\n", __FUNCTION__); | 73 | dprintk("%s: call statfs\n", __FUNCTION__); |
| 74 | msg.rpc_proc = &nfs_procedures[NFSPROC_STATFS]; | 74 | msg.rpc_proc = &nfs_procedures[NFSPROC_STATFS]; |
| 75 | msg.rpc_resp = &fsinfo; | 75 | msg.rpc_resp = &fsinfo; |
| 76 | status = rpc_call_sync(server->client_sys, &msg, 0); | 76 | status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0); |
| 77 | dprintk("%s: reply statfs: %d\n", __FUNCTION__, status); | 77 | dprintk("%s: reply statfs: %d\n", __FUNCTION__, status); |
| 78 | if (status) | 78 | if (status) |
| 79 | return status; | 79 | return status; |
| @@ -425,16 +425,17 @@ nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) · 345 unmodified lines | |||
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | static int | 427 | static int |
| 428 | nfs_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path, | 428 | nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, |
| 429 | struct iattr *sattr, struct nfs_fh *fhandle, | 429 | unsigned int len, struct iattr *sattr) |
| 430 | struct nfs_fattr *fattr) | ||
| 431 | { | 430 | { |
| 431 | struct nfs_fh fhandle; | ||
| 432 | struct nfs_fattr fattr; | ||
| 432 | struct nfs_symlinkargs arg = { | 433 | struct nfs_symlinkargs arg = { |
| 433 | .fromfh = NFS_FH(dir), | 434 | .fromfh = NFS_FH(dir), |
| 434 | .fromname = name->name, | 435 | .fromname = dentry->d_name.name, |
| 435 | .fromlen = name->len, | 436 | .fromlen = dentry->d_name.len, |
| 436 | .topath = path->name, | 437 | .pages = &page, |
| 437 | .tolen = path->len, | 438 | .pathlen = len, |
| 438 | .sattr = sattr | 439 | .sattr = sattr |
| 439 | }; | 440 | }; |
| 440 | struct rpc_message msg = { | 441 | struct rpc_message msg = { |
| @@ -443,13 +444,25 @@ nfs_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path, · 2 unmodified lines | |||
| 443 | }; | 444 | }; |
| 444 | int status; | 445 | int status; |
| 445 | 446 | ||
| 446 | if (path->len > NFS2_MAXPATHLEN) | 447 | if (len > NFS2_MAXPATHLEN) |
| 447 | return -ENAMETOOLONG; | 448 | return -ENAMETOOLONG; |
| 448 | dprintk("NFS call symlink %s -> %s\n", name->name, path->name); | 449 | |
| 449 | nfs_fattr_init(fattr); | 450 | dprintk("NFS call symlink %s\n", dentry->d_name.name); |
| 450 | fhandle->size = 0; | 451 | |
| 451 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 452 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
| 452 | nfs_mark_for_revalidate(dir); | 453 | nfs_mark_for_revalidate(dir); |
| 454 | |||
| 455 | /* | ||
| 456 | * V2 SYMLINK requests don't return any attributes. Setting the | ||
| 457 | * filehandle size to zero indicates to nfs_instantiate that it | ||
| 458 | * should fill in the data with a LOOKUP call on the wire. | ||
| 459 | */ | ||
| 460 | if (status == 0) { | ||
| 461 | nfs_fattr_init(&fattr); | ||
| 462 | fhandle.size = 0; | ||
| 463 | status = nfs_instantiate(dentry, &fhandle, &fattr); | ||
| 464 | } | ||
| 465 | |||
| 453 | dprintk("NFS reply symlink: %d\n", status); | 466 | dprintk("NFS reply symlink: %d\n", status); |
| 454 | return status; | 467 | return status; |
| 455 | } | 468 | } |
| @@ -671,7 +684,7 @@ nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl) · 215 unmodified lines | |||
| 671 | } | 684 | } |
| 672 | 685 | ||
| 673 | 686 | ||
| 674 | struct nfs_rpc_ops nfs_v2_clientops = { | 687 | const struct nfs_rpc_ops nfs_v2_clientops = { |
| 675 | .version = 2, /* protocol version */ | 688 | .version = 2, /* protocol version */ |
| 676 | .dentry_ops = &nfs_dentry_operations, | 689 | .dentry_ops = &nfs_dentry_operations, |
| 677 | .dir_inode_ops = &nfs_dir_inode_operations, | 690 | .dir_inode_ops = &nfs_dir_inode_operations, |
| @@ -171,7 +171,7 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode, · 170 unmodified lines | |||
| 171 | rdata->args.offset = page_offset(page) + rdata->args.pgbase; | 171 | rdata->args.offset = page_offset(page) + rdata->args.pgbase; |
| 172 | 172 | ||
| 173 | dprintk("NFS: nfs_proc_read(%s, (%s/%Ld), %Lu, %u)\n", | 173 | dprintk("NFS: nfs_proc_read(%s, (%s/%Ld), %Lu, %u)\n", |
| 174 | NFS_SERVER(inode)->hostname, | 174 | NFS_SERVER(inode)->nfs_client->cl_hostname, |
| 175 | inode->i_sb->s_id, | 175 | inode->i_sb->s_id, |
| 176 | (long long)NFS_FILEID(inode), | 176 | (long long)NFS_FILEID(inode), |
| 177 | (unsigned long long)rdata->args.pgbase, | 177 | (unsigned long long)rdata->args.pgbase, |
| @@ -568,8 +568,13 @@ int nfs_readpage_result(struct rpc_task *task, struct nfs_read_data *data) · 390 unmodified lines | |||
| 568 | 568 | ||
| 569 | nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, resp->count); | 569 | nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, resp->count); |
| 570 | 570 | ||
| 571 | /* Is this a short read? */ | 571 | if (task->tk_status < 0) { |
| 572 | if (task->tk_status >= 0 && resp->count < argp->count && !resp->eof) { | 572 | if (task->tk_status == -ESTALE) { |
| 573 | set_bit(NFS_INO_STALE, &NFS_FLAGS(data->inode)); | ||
| 574 | nfs_mark_for_revalidate(data->inode); | ||
| 575 | } | ||
| 576 | } else if (resp->count < argp->count && !resp->eof) { | ||
| 577 | /* This is a short read! */ | ||
| 573 | nfs_inc_stats(data->inode, NFSIOS_SHORTREAD); | 578 | nfs_inc_stats(data->inode, NFSIOS_SHORTREAD); |
| 574 | /* Has the server at least made some progress? */ | 579 | /* Has the server at least made some progress? */ |
| 575 | if (resp->count != 0) { | 580 | if (resp->count != 0) { |
| @@ -616,6 +621,10 @@ int nfs_readpage(struct file *file, struct page *page) · 40 unmodified lines | |||
| 616 | if (error) | 621 | if (error) |
| 617 | goto out_error; | 622 | goto out_error; |
| 618 | 623 | ||
| 624 | error = -ESTALE; | ||
| 625 | if (NFS_STALE(inode)) | ||
| 626 | goto out_error; | ||
| 627 | |||
| 619 | if (file == NULL) { | 628 | if (file == NULL) { |
| 620 | ctx = nfs_find_open_context(inode, NULL, FMODE_READ); | 629 | ctx = nfs_find_open_context(inode, NULL, FMODE_READ); |
| 621 | if (ctx == NULL) | 630 | if (ctx == NULL) |
| @@ -678,7 +687,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, · 56 unmodified lines | |||
| 678 | }; | 687 | }; |
| 679 | struct inode *inode = mapping->host; | 688 | struct inode *inode = mapping->host; |
| 680 | struct nfs_server *server = NFS_SERVER(inode); | 689 | struct nfs_server *server = NFS_SERVER(inode); |
| 681 | int ret; | 690 | int ret = -ESTALE; |
| 682 | 691 | ||
| 683 | dprintk("NFS: nfs_readpages (%s/%Ld %d)\n", | 692 | dprintk("NFS: nfs_readpages (%s/%Ld %d)\n", |
| 684 | inode->i_sb->s_id, | 693 | inode->i_sb->s_id, |
| @@ -686,6 +695,9 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, · 1 unmodified line | |||
| 686 | nr_pages); | 695 | nr_pages); |
| 687 | nfs_inc_stats(inode, NFSIOS_VFSREADPAGES); | 696 | nfs_inc_stats(inode, NFSIOS_VFSREADPAGES); |
| 688 | 697 | ||
| 698 | if (NFS_STALE(inode)) | ||
| 699 | goto out; | ||
| 700 | |||
| 689 | if (filp == NULL) { | 701 | if (filp == NULL) { |
| 690 | desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ); | 702 | desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ); |
| 691 | if (desc.ctx == NULL) | 703 | if (desc.ctx == NULL) |
| @@ -701,6 +713,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, · 9 unmodified lines | |||
| 701 | ret = err; | 713 | ret = err; |
| 702 | } | 714 | } |
| 703 | put_nfs_open_context(desc.ctx); | 715 | put_nfs_open_context(desc.ctx); |
| 716 | out: | ||
| 704 | return ret; | 717 | return ret; |
| 705 | } | 718 | } |
| 706 | 719 | ||
| @@ -13,6 +13,11 @@ · 12 unmodified lines | |||
| 13 | * | 13 | * |
| 14 | * Split from inode.c by David Howells <dhowells@redhat.com> | 14 | * Split from inode.c by David Howells <dhowells@redhat.com> |
| 15 | * | 15 | * |
| 16 | * - superblocks are indexed on server only - all inodes, dentries, etc. associated with a | ||
| 17 | * particular server are held in the same superblock | ||
| 18 | * - NFS superblocks can have several effective roots to the dentry tree | ||
| 19 | * - directory type roots are spliced into the tree when a path from one root reaches the root | ||
| 20 | * of another (see nfs_lookup()) | ||
| 16 | */ | 21 | */ |
| 17 | 22 | ||
| 18 | #include <linux/config.h> | 23 | #include <linux/config.h> |
| @@ -52,66 +57,12 @@ · 33 unmodified lines | |||
| 52 | 57 | ||
| 53 | #define NFSDBG_FACILITY NFSDBG_VFS | 58 | #define NFSDBG_FACILITY NFSDBG_VFS |
| 54 | 59 | ||
| 55 | /* Maximum number of readahead requests | ||
| 56 | * FIXME: this should really be a sysctl so that users may tune it to suit | ||
| 57 | * their needs. People that do NFS over a slow network, might for | ||
| 58 | * instance want to reduce it to something closer to 1 for improved | ||
| 59 | * interactive response. | ||
| 60 | */ | ||
| 61 | #define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) | ||
| 62 | |||
| 63 | /* | ||
| 64 | * RPC cruft for NFS | ||
| 65 | */ | ||
| 66 | static struct rpc_version * nfs_version[] = { | ||
| 67 | NULL, | ||
| 68 | NULL, | ||
| 69 | &nfs_version2, | ||
| 70 | #if defined(CONFIG_NFS_V3) | ||
| 71 | &nfs_version3, | ||
| 72 | #elif defined(CONFIG_NFS_V4) | ||
| 73 | NULL, | ||
| 74 | #endif | ||
| 75 | #if defined(CONFIG_NFS_V4) | ||
| 76 | &nfs_version4, | ||
| 77 | #endif | ||
| 78 | }; | ||
| 79 | |||
| 80 | static struct rpc_program nfs_program = { | ||
| 81 | .name = "nfs", | ||
| 82 | .number = NFS_PROGRAM, | ||
| 83 | .nrvers = ARRAY_SIZE(nfs_version), | ||
| 84 | .version = nfs_version, | ||
| 85 | .stats = &nfs_rpcstat, | ||
| 86 | .pipe_dir_name = "/nfs", | ||
| 87 | }; | ||
| 88 | |||
| 89 | struct rpc_stat nfs_rpcstat = { | ||
| 90 | .program = &nfs_program | ||
| 91 | }; | ||
| 92 | |||
| 93 | |||
| 94 | #ifdef CONFIG_NFS_V3_ACL | ||
| 95 | static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program }; | ||
| 96 | static struct rpc_version * nfsacl_version[] = { | ||
| 97 | [3] = &nfsacl_version3, | ||
| 98 | }; | ||
| 99 | |||
| 100 | struct rpc_program nfsacl_program = { | ||
| 101 | .name = "nfsacl", | ||
| 102 | .number = NFS_ACL_PROGRAM, | ||
| 103 | .nrvers = ARRAY_SIZE(nfsacl_version), | ||
| 104 | .version = nfsacl_version, | ||
| 105 | .stats = &nfsacl_rpcstat, | ||
| 106 | }; | ||
| 107 | #endif /* CONFIG_NFS_V3_ACL */ | ||
| 108 | |||
| 109 | static void nfs_umount_begin(struct vfsmount *, int); | 60 | static void nfs_umount_begin(struct vfsmount *, int); |
| 110 | static int nfs_statfs(struct dentry *, struct kstatfs *); | 61 | static int nfs_statfs(struct dentry *, struct kstatfs *); |
| 111 | static int nfs_show_options(struct seq_file *, struct vfsmount *); | 62 | static int nfs_show_options(struct seq_file *, struct vfsmount *); |
| 112 | static int nfs_show_stats(struct seq_file *, struct vfsmount *); | 63 | static int nfs_show_stats(struct seq_file *, struct vfsmount *); |
| 113 | static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); | 64 | static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); |
| 114 | static int nfs_clone_nfs_sb(struct file_system_type *fs_type, | 65 | static int nfs_xdev_get_sb(struct file_system_type *fs_type, |
| 115 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); | 66 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); |
| 116 | static void nfs_kill_super(struct super_block *); | 67 | static void nfs_kill_super(struct super_block *); |
| 117 | 68 | ||
| @@ -123,10 +74,10 @@ static struct file_system_type nfs_fs_type = { · 5 unmodified lines | |||
| 123 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | 74 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, |
| 124 | }; | 75 | }; |
| 125 | 76 | ||
| 126 | struct file_system_type clone_nfs_fs_type = { | 77 | struct file_system_type nfs_xdev_fs_type = { |
| 127 | .owner = THIS_MODULE, | 78 | .owner = THIS_MODULE, |
| 128 | .name = "nfs", | 79 | .name = "nfs", |
| 129 | .get_sb = nfs_clone_nfs_sb, | 80 | .get_sb = nfs_xdev_get_sb, |
| 130 | .kill_sb = nfs_kill_super, | 81 | .kill_sb = nfs_kill_super, |
| 131 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | 82 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, |
| 132 | }; | 83 | }; |
| @@ -145,10 +96,10 @@ static struct super_operations nfs_sops = { · 12 unmodified lines | |||
| 145 | #ifdef CONFIG_NFS_V4 | 96 | #ifdef CONFIG_NFS_V4 |
| 146 | static int nfs4_get_sb(struct file_system_type *fs_type, | 97 | static int nfs4_get_sb(struct file_system_type *fs_type, |
| 147 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); | 98 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); |
| 148 | static int nfs_clone_nfs4_sb(struct file_system_type *fs_type, | 99 | static int nfs4_xdev_get_sb(struct file_system_type *fs_type, |
| 149 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); | 100 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); |
| 150 | static int nfs_referral_nfs4_sb(struct file_system_type *fs_type, | 101 | static int nfs4_referral_get_sb(struct file_system_type *fs_type, |
| 151 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); | 102 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); |
| 152 | static void nfs4_kill_super(struct super_block *sb); | 103 | static void nfs4_kill_super(struct super_block *sb); |
| 153 | 104 | ||
| 154 | static struct file_system_type nfs4_fs_type = { | 105 | static struct file_system_type nfs4_fs_type = { |
| @@ -159,18 +110,18 @@ static struct file_system_type nfs4_fs_type = { · 4 unmodified lines | |||
| 159 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | 110 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, |
| 160 | }; | 111 | }; |
| 161 | 112 | ||
| 162 | struct file_system_type clone_nfs4_fs_type = { | 113 | struct file_system_type nfs4_xdev_fs_type = { |
| 163 | .owner = THIS_MODULE, | 114 | .owner = THIS_MODULE, |
| 164 | .name = "nfs4", | 115 | .name = "nfs4", |
| 165 | .get_sb = nfs_clone_nfs4_sb, | 116 | .get_sb = nfs4_xdev_get_sb, |
| 166 | .kill_sb = nfs4_kill_super, | 117 | .kill_sb = nfs4_kill_super, |
| 167 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | 118 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, |
| 168 | }; | 119 | }; |
| 169 | 120 | ||
| 170 | struct file_system_type nfs_referral_nfs4_fs_type = { | 121 | struct file_system_type nfs4_referral_fs_type = { |
| 171 | .owner = THIS_MODULE, | 122 | .owner = THIS_MODULE, |
| 172 | .name = "nfs4", | 123 | .name = "nfs4", |
| 173 | .get_sb = nfs_referral_nfs4_sb, | 124 | .get_sb = nfs4_referral_get_sb, |
| 174 | .kill_sb = nfs4_kill_super, | 125 | .kill_sb = nfs4_kill_super, |
| 175 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | 126 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, |
| 176 | }; | 127 | }; |
| @@ -187,39 +138,7 @@ static struct super_operations nfs4_sops = { · 10 unmodified lines | |||
| 187 | }; | 138 | }; |
| 188 | #endif | 139 | #endif |
| 189 | 140 | ||
| 190 | #ifdef CONFIG_NFS_V4 | 141 | static struct shrinker *acl_shrinker; |
| 191 | static const int nfs_set_port_min = 0; | ||
| 192 | static const int nfs_set_port_max = 65535; | ||
| 193 | |||
| 194 | static int param_set_port(const char *val, struct kernel_param *kp) | ||
| 195 | { | ||
| 196 | char *endp; | ||
| 197 | int num = simple_strtol(val, &endp, 0); | ||
| 198 | if (endp == val || *endp || num < nfs_set_port_min || num > nfs_set_port_max) | ||
| 199 | return -EINVAL; | ||
| 200 | *((int *)kp->arg) = num; | ||
| 201 | return 0; | ||
| 202 | } | ||
| 203 | |||
| 204 | module_param_call(callback_tcpport, param_set_port, param_get_int, | ||
| 205 | &nfs_callback_set_tcpport, 0644); | ||
| 206 | #endif | ||
| 207 | |||
| 208 | #ifdef CONFIG_NFS_V4 | ||
| 209 | static int param_set_idmap_timeout(const char *val, struct kernel_param *kp) | ||
| 210 | { | ||
| 211 | char *endp; | ||
| 212 | int num = simple_strtol(val, &endp, 0); | ||
| 213 | int jif = num * HZ; | ||
| 214 | if (endp == val || *endp || num < 0 || jif < num) | ||
| 215 | return -EINVAL; | ||
| 216 | *((int *)kp->arg) = jif; | ||
| 217 | return 0; | ||
| 218 | } | ||
| 219 | |||
| 220 | module_param_call(idmap_cache_timeout, param_set_idmap_timeout, param_get_int, | ||
| 221 | &nfs_idmap_cache_timeout, 0644); | ||
| 222 | #endif | ||
| 223 | 142 | ||
| 224 | /* | 143 | /* |
| 225 | * Register the NFS filesystems | 144 | * Register the NFS filesystems |
| @@ -240,6 +159,7 @@ int __init register_nfs_fs(void) · 14 unmodified lines | |||
| 240 | if (ret < 0) | 159 | if (ret < 0) |
| 241 | goto error_2; | 160 | goto error_2; |
| 242 | #endif | 161 | #endif |
| 162 | acl_shrinker = set_shrinker(DEFAULT_SEEKS, nfs_access_cache_shrinker); | ||
| 243 | return 0; | 163 | return 0; |
| 244 | 164 | ||
| 245 | #ifdef CONFIG_NFS_V4 | 165 | #ifdef CONFIG_NFS_V4 |
| @@ -257,6 +177,8 @@ error_0: · 11 unmodified lines | |||
| 257 | */ | 177 | */ |
| 258 | void __exit unregister_nfs_fs(void) | 178 | void __exit unregister_nfs_fs(void) |
| 259 | { | 179 | { |
| 180 | if (acl_shrinker != NULL) | ||
| 181 | remove_shrinker(acl_shrinker); | ||
| 260 | #ifdef CONFIG_NFS_V4 | 182 | #ifdef CONFIG_NFS_V4 |
| 261 | unregister_filesystem(&nfs4_fs_type); | 183 | unregister_filesystem(&nfs4_fs_type); |
| 262 | nfs_unregister_sysctl(); | 184 | nfs_unregister_sysctl(); |
| @@ -269,11 +191,10 @@ void __exit unregister_nfs_fs(void) · 6 unmodified lines | |||
| 269 | */ | 191 | */ |
| 270 | static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 192 | static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
| 271 | { | 193 | { |
| 272 | struct super_block *sb = dentry->d_sb; | 194 | struct nfs_server *server = NFS_SB(dentry->d_sb); |
| 273 | struct nfs_server *server = NFS_SB(sb); | ||
| 274 | unsigned char blockbits; | 195 | unsigned char blockbits; |
| 275 | unsigned long blockres; | 196 | unsigned long blockres; |
| 276 | struct nfs_fh *rootfh = NFS_FH(sb->s_root->d_inode); | 197 | struct nfs_fh *fh = NFS_FH(dentry->d_inode); |
| 277 | struct nfs_fattr fattr; | 198 | struct nfs_fattr fattr; |
| 278 | struct nfs_fsstat res = { | 199 | struct nfs_fsstat res = { |
| 279 | .fattr = &fattr, | 200 | .fattr = &fattr, |
| @@ -282,7 +203,7 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) · 2 unmodified lines | |||
| 282 | 203 | ||
| 283 | lock_kernel(); | 204 | lock_kernel(); |
| 284 | 205 | ||
| 285 | error = server->rpc_ops->statfs(server, rootfh, &res); | 206 | error = server->nfs_client->rpc_ops->statfs(server, fh, &res); |
| 286 | buf->f_type = NFS_SUPER_MAGIC; | 207 | buf->f_type = NFS_SUPER_MAGIC; |
| 287 | if (error < 0) | 208 | if (error < 0) |
| 288 | goto out_err; | 209 | goto out_err; |
| @@ -292,7 +213,7 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) · 3 unmodified lines | |||
| 292 | * case where f_frsize != f_bsize. Eventually we want to | 213 | * case where f_frsize != f_bsize. Eventually we want to |
| 293 | * report the value of wtmult in this field. | 214 | * report the value of wtmult in this field. |
| 294 | */ | 215 | */ |
| 295 | buf->f_frsize = sb->s_blocksize; | 216 | buf->f_frsize = dentry->d_sb->s_blocksize; |
| 296 | 217 | ||
| 297 | /* | 218 | /* |
| 298 | * On most *nix systems, f_blocks, f_bfree, and f_bavail | 219 | * On most *nix systems, f_blocks, f_bfree, and f_bavail |
| @@ -301,8 +222,8 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) · 2 unmodified lines | |||
| 301 | * thus historically Linux's sys_statfs reports these | 222 | * thus historically Linux's sys_statfs reports these |
| 302 | * fields in units of f_bsize. | 223 | * fields in units of f_bsize. |
| 303 | */ | 224 | */ |
| 304 | buf->f_bsize = sb->s_blocksize; | 225 | buf->f_bsize = dentry->d_sb->s_blocksize; |
| 305 | blockbits = sb->s_blocksize_bits; | 226 | blockbits = dentry->d_sb->s_blocksize_bits; |
| 306 | blockres = (1 << blockbits) - 1; | 227 | blockres = (1 << blockbits) - 1; |
| 307 | buf->f_blocks = (res.tbytes + blockres) >> blockbits; | 228 | buf->f_blocks = (res.tbytes + blockres) >> blockbits; |
| 308 | buf->f_bfree = (res.fbytes + blockres) >> blockbits; | 229 | buf->f_bfree = (res.fbytes + blockres) >> blockbits; |
| @@ -323,9 +244,12 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) · 14 unmodified lines | |||
| 323 | 244 | ||
| 324 | } | 245 | } |
| 325 | 246 | ||
| 247 | /* | ||
| 248 | * Map the security flavour number to a name | ||
| 249 | */ | ||
| 326 | static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour) | 250 | static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour) |
| 327 | { | 251 | { |
| 328 | static struct { | 252 | static const struct { |
| 329 | rpc_authflavor_t flavour; | 253 | rpc_authflavor_t flavour; |
| 330 | const char *str; | 254 | const char *str; |
| 331 | } sec_flavours[] = { | 255 | } sec_flavours[] = { |
| @@ -356,10 +280,10 @@ static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour) · 24 unmodified lines | |||
| 356 | */ | 280 | */ |
| 357 | static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, int showdefaults) | 281 | static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, int showdefaults) |
| 358 | { | 282 | { |
| 359 | static struct proc_nfs_info { | 283 | static const struct proc_nfs_info { |
| 360 | int flag; | 284 | int flag; |
| 361 | char *str; | 285 | const char *str; |
| 362 | char *nostr; | 286 | const char *nostr; |
| 363 | } nfs_info[] = { | 287 | } nfs_info[] = { |
| 364 | { NFS_MOUNT_SOFT, ",soft", ",hard" }, | 288 | { NFS_MOUNT_SOFT, ",soft", ",hard" }, |
| 365 | { NFS_MOUNT_INTR, ",intr", "" }, | 289 | { NFS_MOUNT_INTR, ",intr", "" }, |
| @@ -369,11 +293,12 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, · 3 unmodified lines | |||
| 369 | { NFS_MOUNT_NOACL, ",noacl", "" }, | 293 | { NFS_MOUNT_NOACL, ",noacl", "" }, |
| 370 | { 0, NULL, NULL } | 294 | { 0, NULL, NULL } |
| 371 | }; | 295 | }; |
| 372 | struct proc_nfs_info *nfs_infop; | 296 | const struct proc_nfs_info *nfs_infop; |
| 297 | struct nfs_client *clp = nfss->nfs_client; | ||
| 373 | char buf[12]; | 298 | char buf[12]; |
| 374 | char *proto; | 299 | const char *proto; |
| 375 | 300 | ||
| 376 | seq_printf(m, ",vers=%d", nfss->rpc_ops->version); | 301 | seq_printf(m, ",vers=%d", clp->rpc_ops->version); |
| 377 | seq_printf(m, ",rsize=%d", nfss->rsize); | 302 | seq_printf(m, ",rsize=%d", nfss->rsize); |
| 378 | seq_printf(m, ",wsize=%d", nfss->wsize); | 303 | seq_printf(m, ",wsize=%d", nfss->wsize); |
| 379 | if (nfss->acregmin != 3*HZ || showdefaults) | 304 | if (nfss->acregmin != 3*HZ || showdefaults) |
| @@ -402,8 +327,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, · 22 unmodified lines | |||
| 402 | proto = buf; | 327 | proto = buf; |
| 403 | } | 328 | } |
| 404 | seq_printf(m, ",proto=%s", proto); | 329 | seq_printf(m, ",proto=%s", proto); |
| 405 | seq_printf(m, ",timeo=%lu", 10U * nfss->retrans_timeo / HZ); | 330 | seq_printf(m, ",timeo=%lu", 10U * clp->retrans_timeo / HZ); |
| 406 | seq_printf(m, ",retrans=%u", nfss->retrans_count); | 331 | seq_printf(m, ",retrans=%u", clp->retrans_count); |
| 407 | seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor)); | 332 | seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor)); |
| 408 | } | 333 | } |
| 409 | 334 | ||
| @@ -417,7 +342,7 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt) · 7 unmodified lines | |||
| 417 | nfs_show_mount_options(m, nfss, 0); | 342 | nfs_show_mount_options(m, nfss, 0); |
| 418 | 343 | ||
| 419 | seq_puts(m, ",addr="); | 344 | seq_puts(m, ",addr="); |
| 420 | seq_escape(m, nfss->hostname, " \t\n\\"); | 345 | seq_escape(m, nfss->nfs_client->cl_hostname, " \t\n\\"); |
| 421 | 346 | ||
| 422 | return 0; | 347 | return 0; |
| 423 | } | 348 | } |
| @@ -454,7 +379,7 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt) · 30 unmodified lines | |||
| 454 | seq_printf(m, ",namelen=%d", nfss->namelen); | 379 | seq_printf(m, ",namelen=%d", nfss->namelen); |
| 455 | 380 | ||
| 456 | #ifdef CONFIG_NFS_V4 | 381 | #ifdef CONFIG_NFS_V4 |
| 457 | if (nfss->rpc_ops->version == 4) { | 382 | if (nfss->nfs_client->cl_nfsversion == 4) { |
| 458 | seq_printf(m, "\n\tnfsv4:\t"); | 383 | seq_printf(m, "\n\tnfsv4:\t"); |
| 459 | seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]); | 384 | seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]); |
| 460 | seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]); | 385 | seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]); |
| @@ -501,782 +426,353 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt) · 40 unmodified lines | |||
| 501 | 426 | ||
| 502 | /* | 427 | /* |
| 503 | * Begin unmount by attempting to remove all automounted mountpoints we added | 428 | * Begin unmount by attempting to remove all automounted mountpoints we added |
| 504 | * in response to traversals | 429 | * in response to xdev traversals and referrals |
| 505 | */ | 430 | */ |
| 506 | static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags) | 431 | static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags) |
| 507 | { | 432 | { |
| 508 | struct nfs_server *server; | ||
| 509 | struct rpc_clnt *rpc; | ||
| 510 | |||
| 511 | shrink_submounts(vfsmnt, &nfs_automount_list); | 433 | shrink_submounts(vfsmnt, &nfs_automount_list); |
| 512 | if (!(flags & MNT_FORCE)) | ||
| 513 | return; | ||
| 514 | /* -EIO all pending I/O */ | ||
| 515 | server = NFS_SB(vfsmnt->mnt_sb); | ||
| 516 | rpc = server->client; | ||
| 517 | if (!IS_ERR(rpc)) | ||
| 518 | rpc_killall_tasks(rpc); | ||
| 519 | rpc = server->client_acl; | ||
| 520 | if (!IS_ERR(rpc)) | ||
| 521 | rpc_killall_tasks(rpc); | ||
| 522 | } | 434 | } |
| 523 | 435 | ||
| 524 | /* | 436 | /* |
| 525 | * Obtain the root inode of the file system. | 437 | * Validate the NFS2/NFS3 mount data |
| 438 | * - fills in the mount root filehandle | ||
| 526 | */ | 439 | */ |
| 527 | static struct inode * | 440 | static int nfs_validate_mount_data(struct nfs_mount_data *data, |
| 528 | nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *fsinfo) | 441 | struct nfs_fh *mntfh) |
| 529 | { | 442 | { |
| 530 | struct nfs_server *server = NFS_SB(sb); | 443 | if (data == NULL) { |
| 531 | int error; | 444 | dprintk("%s: missing data argument\n", __FUNCTION__); |
| 532 | 445 | return -EINVAL; | |
| 533 | error = server->rpc_ops->getroot(server, rootfh, fsinfo); | ||
| 534 | if (error < 0) { | ||
| 535 | dprintk("nfs_get_root: getattr error = %d\n", -error); | ||
| 536 | return ERR_PTR(error); | ||
| 537 | } | 446 | } |
| 538 | 447 | ||
| 539 | server->fsid = fsinfo->fattr->fsid; | 448 | if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) { |
| 540 | return nfs_fhget(sb, rootfh, fsinfo->fattr); | 449 | dprintk("%s: bad mount version\n", __FUNCTION__); |
| 541 | } | 450 | return -EINVAL; |
| 542 | 451 | } | |
| 543 | /* | ||
| 544 | * Do NFS version-independent mount processing, and sanity checking | ||
| 545 | */ | ||
| 546 | static int | ||
| 547 | nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor) | ||
| 548 | { | ||
| 549 | struct nfs_server *server; | ||
| 550 | struct inode *root_inode; | ||
| 551 | struct nfs_fattr fattr; | ||
| 552 | struct nfs_fsinfo fsinfo = { | ||
| 553 | .fattr = &fattr, | ||
| 554 | }; | ||
| 555 | struct nfs_pathconf pathinfo = { | ||
| 556 | .fattr = &fattr, | ||
| 557 | }; | ||
| 558 | int no_root_error = 0; | ||
| 559 | unsigned long max_rpc_payload; | ||
| 560 | |||
| 561 | /* We probably want something more informative here */ | ||
| 562 | snprintf(sb->s_id, sizeof(sb->s_id), "%x:%x", MAJOR(sb->s_dev), MINOR(sb->s_dev)); | ||
| 563 | |||
| 564 | server = NFS_SB(sb); | ||
| 565 | 452 | ||
| 566 | sb->s_magic = NFS_SUPER_MAGIC; | 453 | switch (data->version) { |
| 454 | case 1: | ||
| 455 | data->namlen = 0; | ||
| 456 | case 2: | ||
| 457 | data->bsize = 0; | ||
| 458 | case 3: | ||
| 459 | if (data->flags & NFS_MOUNT_VER3) { | ||
| 460 | dprintk("%s: mount structure version %d does not support NFSv3\n", | ||
| 461 | __FUNCTION__, | ||
| 462 | data->version); | ||
| 463 | return -EINVAL; | ||
| 464 | } | ||
| 465 | data->root.size = NFS2_FHSIZE; | ||
| 466 | memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); | ||
| 467 | case 4: | ||
| 468 | if (data->flags & NFS_MOUNT_SECFLAVOUR) { | ||
| 469 | dprintk("%s: mount structure version %d does not support strong security\n", | ||
| 470 | __FUNCTION__, | ||
| 471 | data->version); | ||
| 472 | return -EINVAL; | ||
| 473 | } | ||
| 474 | case 5: | ||
| 475 | memset(data->context, 0, sizeof(data->context)); | ||
| 476 | } | ||
| 567 | 477 | ||
| 568 | server->io_stats = nfs_alloc_iostats(); | 478 | /* Set the pseudoflavor */ |
| 569 | if (server->io_stats == NULL) | 479 | if (!(data->flags & NFS_MOUNT_SECFLAVOUR)) |
| 570 | return -ENOMEM; | 480 | data->pseudoflavor = RPC_AUTH_UNIX; |
| 571 | 481 | ||
| 572 | root_inode = nfs_get_root(sb, &server->fh, &fsinfo); | 482 | #ifndef CONFIG_NFS_V3 |
| 573 | /* Did getting the root inode fail? */ | 483 | /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */ |
| 574 | if (IS_ERR(root_inode)) { | 484 | if (data->flags & NFS_MOUNT_VER3) { |
| 575 | no_root_error = PTR_ERR(root_inode); | 485 | dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__); |
| 576 | goto out_no_root; | 486 | return -EPROTONOSUPPORT; |
| 577 | } | ||
| 578 | sb->s_root = d_alloc_root(root_inode); | ||
| 579 | if (!sb->s_root) { | ||
| 580 | no_root_error = -ENOMEM; | ||
| 581 | goto out_no_root; | ||
| 582 | } | 487 | } |
| 583 | sb->s_root->d_op = server->rpc_ops->dentry_ops; | 488 | #endif /* CONFIG_NFS_V3 */ |
| 584 | |||
| 585 | /* mount time stamp, in seconds */ | ||
| 586 | server->mount_time = jiffies; | ||
| 587 | |||
| 588 | /* Get some general file system info */ | ||
| 589 | if (server->namelen == 0 && | ||
| 590 | server->rpc_ops->pathconf(server, &server->fh, &pathinfo) >= 0) | ||
| 591 | server->namelen = pathinfo.max_namelen; | ||
| 592 | /* Work out a lot of parameters */ | ||
| 593 | if (server->rsize == 0) | ||
| 594 | server->rsize = nfs_block_size(fsinfo.rtpref, NULL); | ||
| 595 | if (server->wsize == 0) | ||
| 596 | server->wsize = nfs_block_size(fsinfo.wtpref, NULL); | ||
| 597 | |||
| 598 | if (fsinfo.rtmax >= 512 && server->rsize > fsinfo.rtmax) | ||
| 599 | server->rsize = nfs_block_size(fsinfo.rtmax, NULL); | ||
| 600 | if (fsinfo.wtmax >= 512 && server->wsize > fsinfo.wtmax) | ||
| 601 | server->wsize = nfs_block_size(fsinfo.wtmax, NULL); | ||
| 602 | |||
| 603 | max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL); | ||
| 604 | if (server->rsize > max_rpc_payload) | ||
| 605 | server->rsize = max_rpc_payload; | ||
| 606 | if (server->rsize > NFS_MAX_FILE_IO_SIZE) | ||
| 607 | server->rsize = NFS_MAX_FILE_IO_SIZE; | ||
| 608 | server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | ||
| 609 | |||
| 610 | if (server->wsize > max_rpc_payload) | ||
| 611 | server->wsize = max_rpc_payload; | ||
| 612 | if (server->wsize > NFS_MAX_FILE_IO_SIZE) | ||
| 613 | server->wsize = NFS_MAX_FILE_IO_SIZE; | ||
| 614 | server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | ||
| 615 | 489 | ||
| 616 | if (sb->s_blocksize == 0) | 490 | /* We now require that the mount process passes the remote address */ |
| 617 | sb->s_blocksize = nfs_block_bits(server->wsize, | 491 | if (data->addr.sin_addr.s_addr == INADDR_ANY) { |
| 618 | &sb->s_blocksize_bits); | 492 | dprintk("%s: mount program didn't pass remote address!\n", |
| 619 | server->wtmult = nfs_block_bits(fsinfo.wtmult, NULL); | 493 | __FUNCTION__); |
| 620 | 494 | return -EINVAL; | |
| 621 | server->dtsize = nfs_block_size(fsinfo.dtpref, NULL); | ||
| 622 | if (server->dtsize > PAGE_CACHE_SIZE) | ||
| 623 | server->dtsize = PAGE_CACHE_SIZE; | ||
| 624 | if (server->dtsize > server->rsize) | ||
| 625 | server->dtsize = server->rsize; | ||
| 626 | |||
| 627 | if (server->flags & NFS_MOUNT_NOAC) { | ||
| 628 | server->acregmin = server->acregmax = 0; | ||
| 629 | server->acdirmin = server->acdirmax = 0; | ||
| 630 | sb->s_flags |= MS_SYNCHRONOUS; | ||
| 631 | } | 495 | } |
| 632 | server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD; | ||
| 633 | 496 | ||
| 634 | nfs_super_set_maxbytes(sb, fsinfo.maxfilesize); | 497 | /* Prepare the root filehandle */ |
| 498 | if (data->flags & NFS_MOUNT_VER3) | ||
| 499 | mntfh->size = data->root.size; | ||
| 500 | else | ||
| 501 | mntfh->size = NFS2_FHSIZE; | ||
| 502 | |||
| 503 | if (mntfh->size > sizeof(mntfh->data)) { | ||
| 504 | dprintk("%s: invalid root filehandle\n", __FUNCTION__); | ||
| 505 | return -EINVAL; | ||
| 506 | } | ||
| 635 | 507 | ||
| 636 | server->client->cl_intr = (server->flags & NFS_MOUNT_INTR) ? 1 : 0; | 508 | memcpy(mntfh->data, data->root.data, mntfh->size); |
| 637 | server->client->cl_softrtry = (server->flags & NFS_MOUNT_SOFT) ? 1 : 0; | 509 | if (mntfh->size < sizeof(mntfh->data)) |
| 510 | memset(mntfh->data + mntfh->size, 0, | ||
| 511 | sizeof(mntfh->data) - mntfh->size); | ||
| 638 | 512 | ||
| 639 | /* We're airborne Set socket buffersize */ | ||
| 640 | rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100); | ||
| 641 | return 0; | 513 | return 0; |
| 642 | /* Yargs. It didn't work out. */ | ||
| 643 | out_no_root: | ||
| 644 | dprintk("nfs_sb_init: get root inode failed: errno %d\n", -no_root_error); | ||
| 645 | if (!IS_ERR(root_inode)) | ||
| 646 | iput(root_inode); | ||
| 647 | return no_root_error; | ||
| 648 | } | 514 | } |
| 649 | 515 | ||
| 650 | /* | 516 | /* |
| 651 | * Initialise the timeout values for a connection | 517 | * Initialise the common bits of the superblock |
| 652 | */ | 518 | */ |
| 653 | static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, unsigned int timeo, unsigned int retrans) | 519 | static inline void nfs_initialise_sb(struct super_block *sb) |
| 654 | { | 520 | { |
| 655 | to->to_initval = timeo * HZ / 10; | 521 | struct nfs_server *server = NFS_SB(sb); |
| 656 | to->to_retries = retrans; | ||
| 657 | if (!to->to_retries) | ||
| 658 | to->to_retries = 2; | ||
| 659 | |||
| 660 | switch (proto) { | ||
| 661 | case IPPROTO_TCP: | ||
| 662 | if (!to->to_initval) | ||
| 663 | to->to_initval = 60 * HZ; | ||
| 664 | if (to->to_initval > NFS_MAX_TCP_TIMEOUT) | ||
| 665 | to->to_initval = NFS_MAX_TCP_TIMEOUT; | ||
| 666 | to->to_increment = to->to_initval; | ||
| 667 | to->to_maxval = to->to_initval + (to->to_increment * to->to_retries); | ||
| 668 | to->to_exponential = 0; | ||
| 669 | break; | ||
| 670 | case IPPROTO_UDP: | ||
| 671 | default: | ||
| 672 | if (!to->to_initval) | ||
| 673 | to->to_initval = 11 * HZ / 10; | ||
| 674 | if (to->to_initval > NFS_MAX_UDP_TIMEOUT) | ||
| 675 | to->to_initval = NFS_MAX_UDP_TIMEOUT; | ||
| 676 | to->to_maxval = NFS_MAX_UDP_TIMEOUT; | ||
| 677 | to->to_exponential = 1; | ||
| 678 | break; | ||
| 679 | } | ||
| 680 | } | ||
| 681 | 522 | ||
| 682 | /* | 523 | sb->s_magic = NFS_SUPER_MAGIC; |
| 683 | * Create an RPC client handle. | ||
| 684 | */ | ||
| 685 | static struct rpc_clnt * | ||
| 686 | nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) | ||
| 687 | { | ||
| 688 | struct rpc_timeout timeparms; | ||
| 689 | struct rpc_xprt *xprt = NULL; | ||
| 690 | struct rpc_clnt *clnt = NULL; | ||
| 691 | int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP; | ||
| 692 | |||
| 693 | nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans); | ||
| 694 | |||
| 695 | server->retrans_timeo = timeparms.to_initval; | ||
| 696 | server->retrans_count = timeparms.to_retries; | ||
| 697 | |||
| 698 | /* create transport and client */ | ||
| 699 | xprt = xprt_create_proto(proto, &server->addr, &timeparms); | ||
| 700 | if (IS_ERR(xprt)) { | ||
| 701 | dprintk("%s: cannot create RPC transport. Error = %ld\n", | ||
| 702 | __FUNCTION__, PTR_ERR(xprt)); | ||
| 703 | return (struct rpc_clnt *)xprt; | ||
| 704 | } | ||
| 705 | clnt = rpc_create_client(xprt, server->hostname, &nfs_program, | ||
| 706 | server->rpc_ops->version, data->pseudoflavor); | ||
| 707 | if (IS_ERR(clnt)) { | ||
| 708 | dprintk("%s: cannot create RPC client. Error = %ld\n", | ||
| 709 | __FUNCTION__, PTR_ERR(xprt)); | ||
| 710 | goto out_fail; | ||
| 711 | } | ||
| 712 | 524 | ||
| 713 | clnt->cl_intr = 1; | 525 | /* We probably want something more informative here */ |
| 714 | clnt->cl_softrtry = 1; | 526 | snprintf(sb->s_id, sizeof(sb->s_id), |
| 527 | "%x:%x", MAJOR(sb->s_dev), MINOR(sb->s_dev)); | ||
| 528 | |||
| 529 | if (sb->s_blocksize == 0) | ||
| 530 | sb->s_blocksize = nfs_block_bits(server->wsize, | ||
| 531 | &sb->s_blocksize_bits); | ||
| 715 | 532 | ||
| 716 | return clnt; | 533 | if (server->flags & NFS_MOUNT_NOAC) |
| 534 | sb->s_flags |= MS_SYNCHRONOUS; | ||
| 717 | 535 | ||
| 718 | out_fail: | 536 | nfs_super_set_maxbytes(sb, server->maxfilesize); |
| 719 | return clnt; | ||
| 720 | } | 537 | } |
| 721 | 538 | ||
| 722 | /* | 539 | /* |
| 723 | * Clone a server record | 540 | * Finish setting up an NFS2/3 superblock |
| 724 | */ | 541 | */ |
| 725 | static struct nfs_server *nfs_clone_server(struct super_block *sb, struct nfs_clone_mount *data) | 542 | static void nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data) |
| 726 | { | 543 | { |
| 727 | struct nfs_server *server = NFS_SB(sb); | 544 | struct nfs_server *server = NFS_SB(sb); |
| 728 | struct nfs_server *parent = NFS_SB(data->sb); | ||
| 729 | struct inode *root_inode; | ||
| 730 | struct nfs_fsinfo fsinfo; | ||
| 731 | void *err = ERR_PTR(-ENOMEM); | ||
| 732 | |||
| 733 | sb->s_op = data->sb->s_op; | ||
| 734 | sb->s_blocksize = data->sb->s_blocksize; | ||
| 735 | sb->s_blocksize_bits = data->sb->s_blocksize_bits; | ||
| 736 | sb->s_maxbytes = data->sb->s_maxbytes; | ||
| 737 | |||
| 738 | server->client_sys = server->client_acl = ERR_PTR(-EINVAL); | ||
| 739 | server->io_stats = nfs_alloc_iostats(); | ||
| 740 | if (server->io_stats == NULL) | ||
| 741 | goto out; | ||
| 742 | |||
| 743 | server->client = rpc_clone_client(parent->client); | ||
| 744 | if (IS_ERR((err = server->client))) | ||
| 745 | goto out; | ||
| 746 | |||
| 747 | if (!IS_ERR(parent->client_sys)) { | ||
| 748 | server->client_sys = rpc_clone_client(parent->client_sys); | ||
| 749 | if (IS_ERR((err = server->client_sys))) | ||
| 750 | goto out; | ||
| 751 | } | ||
| 752 | if (!IS_ERR(parent->client_acl)) { | ||
| 753 | server->client_acl = rpc_clone_client(parent->client_acl); | ||
| 754 | if (IS_ERR((err = server->client_acl))) | ||
| 755 | goto out; | ||
| 756 | } | ||
| 757 | root_inode = nfs_fhget(sb, data->fh, data->fattr); | ||
| 758 | if (!root_inode) | ||
| 759 | goto out; | ||
| 760 | sb->s_root = d_alloc_root(root_inode); | ||
| 761 | if (!sb->s_root) | ||
| 762 | goto out_put_root; | ||
| 763 | fsinfo.fattr = data->fattr; | ||
| 764 | if (NFS_PROTO(root_inode)->fsinfo(server, data->fh, &fsinfo) == 0) | ||
| 765 | nfs_super_set_maxbytes(sb, fsinfo.maxfilesize); | ||
| 766 | sb->s_root->d_op = server->rpc_ops->dentry_ops; | ||
| 767 | sb->s_flags |= MS_ACTIVE; | ||
| 768 | return server; | ||
| 769 | out_put_root: | ||
| 770 | iput(root_inode); | ||
| 771 | out: | ||
| 772 | return err; | ||
| 773 | } | ||
| 774 | 545 | ||
| 775 | /* | 546 | sb->s_blocksize_bits = 0; |
| 776 | * Copy an existing superblock and attach revised data | 547 | sb->s_blocksize = 0; |
| 777 | */ | 548 | if (data->bsize) |
| 778 | static int nfs_clone_generic_sb(struct nfs_clone_mount *data, | 549 | sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits); |
| 779 | struct super_block *(*fill_sb)(struct nfs_server *, struct nfs_clone_mount *), | ||
| 780 | struct nfs_server *(*fill_server)(struct super_block *, struct nfs_clone_mount *), | ||
| 781 | struct vfsmount *mnt) | ||
| 782 | { | ||
| 783 | struct nfs_server *server; | ||
| 784 | struct nfs_server *parent = NFS_SB(data->sb); | ||
| 785 | struct super_block *sb = ERR_PTR(-EINVAL); | ||
| 786 | char *hostname; | ||
| 787 | int error = -ENOMEM; | ||
| 788 | int len; | ||
| 789 | |||
| 790 | server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL); | ||
| 791 | if (server == NULL) | ||
| 792 | goto out_err; | ||
| 793 | memcpy(server, parent, sizeof(*server)); | ||
| 794 | hostname = (data->hostname != NULL) ? data->hostname : parent->hostname; | ||
| 795 | len = strlen(hostname) + 1; | ||
| 796 | server->hostname = kmalloc(len, GFP_KERNEL); | ||
| 797 | if (server->hostname == NULL) | ||
| 798 | goto free_server; | ||
| 799 | memcpy(server->hostname, hostname, len); | ||
| 800 | error = rpciod_up(); | ||
| 801 | if (error != 0) | ||
| 802 | goto free_hostname; | ||
| 803 | |||
| 804 | sb = fill_sb(server, data); | ||
| 805 | if (IS_ERR(sb)) { | ||
| 806 | error = PTR_ERR(sb); | ||
| 807 | goto kill_rpciod; | ||
| 808 | } | ||
| 809 | |||
| 810 | if (sb->s_root) | ||
| 811 | goto out_rpciod_down; | ||
| 812 | 550 | ||
| 813 | server = fill_server(sb, data); | 551 | if (server->flags & NFS_MOUNT_VER3) { |
| 814 | if (IS_ERR(server)) { | 552 | /* The VFS shouldn't apply the umask to mode bits. We will do |
| 815 | error = PTR_ERR(server); | 553 | * so ourselves when necessary. |
| 816 | goto out_deactivate; | 554 | */ |
| 555 | sb->s_flags |= MS_POSIXACL; | ||
| 556 | sb->s_time_gran = 1; | ||
| 817 | } | 557 | } |
| 818 | return simple_set_mnt(mnt, sb); | 558 | |
| 819 | out_deactivate: | 559 | sb->s_op = &nfs_sops; |
| 820 | up_write(&sb->s_umount); | 560 | nfs_initialise_sb(sb); |
| 821 | deactivate_super(sb); | ||
| 822 | return error; | ||
| 823 | out_rpciod_down: | ||
| 824 | rpciod_down(); | ||
| 825 | kfree(server->hostname); | ||
| 826 | kfree(server); | ||
| 827 | return simple_set_mnt(mnt, sb); | ||
| 828 | kill_rpciod: | ||
| 829 | rpciod_down(); | ||
| 830 | free_hostname: | ||
| 831 | kfree(server->hostname); | ||
| 832 | free_server: | ||
| 833 | kfree(server); | ||
| 834 | out_err: | ||
| 835 | return error; | ||
| 836 | } | 561 | } |
| 837 | 562 | ||
| 838 | /* | 563 | /* |
| 839 | * Set up an NFS2/3 superblock | 564 | * Finish setting up a cloned NFS2/3 superblock |
| 840 | * | ||
| 841 | * The way this works is that the mount process passes a structure | ||
| 842 | * in the data argument which contains the server's IP address | ||
| 843 | * and the root file handle obtained from the server's mount | ||
| 844 | * daemon. We stash these away in the private superblock fields. | ||
| 845 | */ | 565 | */ |
| 846 | static int | 566 | static void nfs_clone_super(struct super_block *sb, |
| 847 | nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) | 567 | const struct super_block *old_sb) |
| 848 | { | 568 | { |
| 849 | struct nfs_server *server; | 569 | struct nfs_server *server = NFS_SB(sb); |
| 850 | rpc_authflavor_t authflavor; | ||
| 851 | 570 | ||
| 852 | server = NFS_SB(sb); | 571 | sb->s_blocksize_bits = old_sb->s_blocksize_bits; |
| 853 | sb->s_blocksize_bits = 0; | 572 | sb->s_blocksize = old_sb->s_blocksize; |
| 854 | sb->s_blocksize = 0; | 573 | sb->s_maxbytes = old_sb->s_maxbytes; |
| 855 | if (data->bsize) | ||
| 856 | sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits); | ||
| 857 | if (data->rsize) | ||
| 858 | server->rsize = nfs_block_size(data->rsize, NULL); | ||
| 859 | if (data->wsize) | ||
| 860 | server->wsize = nfs_block_size(data->wsize, NULL); | ||
| 861 | server->flags = data->flags & NFS_MOUNT_FLAGMASK; | ||
| 862 | |||
| 863 | server->acregmin = data->acregmin*HZ; | ||
| 864 | server->acregmax = data->acregmax*HZ; | ||
| 865 | server->acdirmin = data->acdirmin*HZ; | ||
| 866 | server->acdirmax = data->acdirmax*HZ; | ||
| 867 | |||
| 868 | /* Start lockd here, before we might error out */ | ||
| 869 | if (!(server->flags & NFS_MOUNT_NONLM)) | ||
| 870 | lockd_up(); | ||
| 871 | |||
| 872 | server->namelen = data->namlen; | ||
| 873 | server->hostname = kmalloc(strlen(data->hostname) + 1, GFP_KERNEL); | ||
| 874 | if (!server->hostname) | ||
| 875 | return -ENOMEM; | ||
| 876 | strcpy(server->hostname, data->hostname); | ||
| 877 | |||
| 878 | /* Check NFS protocol revision and initialize RPC op vector | ||
| 879 | * and file handle pool. */ | ||
| 880 | #ifdef CONFIG_NFS_V3 | ||
| 881 | if (server->flags & NFS_MOUNT_VER3) { | ||
| 882 | server->rpc_ops = &nfs_v3_clientops; | ||
| 883 | server->caps |= NFS_CAP_READDIRPLUS; | ||
| 884 | } else { | ||
| 885 | server->rpc_ops = &nfs_v2_clientops; | ||
| 886 | } | ||
| 887 | #else | ||
| 888 | server->rpc_ops = &nfs_v2_clientops; | ||
| 889 | #endif | ||
| 890 | 574 | ||
| 891 | /* Fill in pseudoflavor for mount version < 5 */ | ||
| 892 | if (!(data->flags & NFS_MOUNT_SECFLAVOUR)) | ||
| 893 | data->pseudoflavor = RPC_AUTH_UNIX; | ||
| 894 | authflavor = data->pseudoflavor; /* save for sb_init() */ | ||
| 895 | /* XXX maybe we want to add a server->pseudoflavor field */ | ||
| 896 | |||
| 897 | /* Create RPC client handles */ | ||
| 898 | server->client = nfs_create_client(server, data); | ||
| 899 | if (IS_ERR(server->client)) | ||
| 900 | return PTR_ERR(server->client); | ||
| 901 | /* RFC 2623, sec 2.3.2 */ | ||
| 902 | if (authflavor != RPC_AUTH_UNIX) { | ||
| 903 | struct rpc_auth *auth; | ||
| 904 | |||
| 905 | server->client_sys = rpc_clone_client(server->client); | ||
| 906 | if (IS_ERR(server->client_sys)) | ||
| 907 | return PTR_ERR(server->client_sys); | ||
| 908 | auth = rpcauth_create(RPC_AUTH_UNIX, server->client_sys); | ||
| 909 | if (IS_ERR(auth)) | ||
| 910 | return PTR_ERR(auth); | ||
| 911 | } else { | ||
| 912 | atomic_inc(&server->client->cl_count); | ||
| 913 | server->client_sys = server->client; | ||
| 914 | } | ||
| 915 | if (server->flags & NFS_MOUNT_VER3) { | 575 | if (server->flags & NFS_MOUNT_VER3) { |
| 916 | #ifdef CONFIG_NFS_V3_ACL | 576 | /* The VFS shouldn't apply the umask to mode bits. We will do |
| 917 | if (!(server->flags & NFS_MOUNT_NOACL)) { | 577 | * so ourselves when necessary. |
| 918 | server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3); | ||
| 919 | /* No errors! Assume that Sun nfsacls are supported */ | ||
| 920 | if (!IS_ERR(server->client_acl)) | ||
| 921 | server->caps |= NFS_CAP_ACLS; | ||
| 922 | } | ||
| 923 | #else | ||
| 924 | server->flags &= ~NFS_MOUNT_NOACL; | ||
| 925 | #endif /* CONFIG_NFS_V3_ACL */ | ||
| 926 | /* | ||
| 927 | * The VFS shouldn't apply the umask to mode bits. We will | ||
| 928 | * do so ourselves when necessary. | ||
| 929 | */ | 578 | */ |
| 930 | sb->s_flags |= MS_POSIXACL; | 579 | sb->s_flags |= MS_POSIXACL; |
| 931 | if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) | ||
| 932 | server->namelen = NFS3_MAXNAMLEN; | ||
| 933 | sb->s_time_gran = 1; | 580 | sb->s_time_gran = 1; |
| 934 | } else { | ||
| 935 | if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN) | ||
| 936 | server->namelen = NFS2_MAXNAMLEN; | ||
| 937 | } | 581 | } |
| 938 | 582 | ||
| 939 | sb->s_op = &nfs_sops; | 583 | sb->s_op = old_sb->s_op; |
| 940 | return nfs_sb_init(sb, authflavor); | 584 | nfs_initialise_sb(sb); |
| 941 | } | 585 | } |
| 942 | 586 | ||
| 943 | static int nfs_set_super(struct super_block *s, void *data) | 587 | static int nfs_set_super(struct super_block *s, void *_server) |
| 944 | { | 588 | { |
| 945 | s->s_fs_info = data; | 589 | struct nfs_server *server = _server; |
| 946 | return set_anon_super(s, data); | 590 | int ret; |
| 591 | |||
| 592 | s->s_fs_info = server; | ||
| 593 | ret = set_anon_super(s, server); | ||
| 594 | if (ret == 0) | ||
| 595 | server->s_dev = s->s_dev; | ||
| 596 | return ret; | ||
| 947 | } | 597 | } |
| 948 | 598 | ||
| 949 | static int nfs_compare_super(struct super_block *sb, void *data) | 599 | static int nfs_compare_super(struct super_block *sb, void *data) |
| 950 | { | 600 | { |
| 951 | struct nfs_server *server = data; | 601 | struct nfs_server *server = data, *old = NFS_SB(sb); |
| 952 | struct nfs_server *old = NFS_SB(sb); | ||
| 953 | 602 | ||
| 954 | if (old->addr.sin_addr.s_addr != server->addr.sin_addr.s_addr) | 603 | if (old->nfs_client != server->nfs_client) |
| 955 | return 0; | 604 | return 0; |
| 956 | if (old->addr.sin_port != server->addr.sin_port) | 605 | if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0) |
| 957 | return 0; | 606 | return 0; |
| 958 | return !nfs_compare_fh(&old->fh, &server->fh); | 607 | return 1; |
| 959 | } | 608 | } |
| 960 | 609 | ||
| 961 | static int nfs_get_sb(struct file_system_type *fs_type, | 610 | static int nfs_get_sb(struct file_system_type *fs_type, |
| 962 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) | 611 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) |
| 963 | { | 612 | { |
| 964 | int error; | ||
| 965 | struct nfs_server *server = NULL; | 613 | struct nfs_server *server = NULL; |
| 966 | struct super_block *s; | 614 | struct super_block *s; |
| 967 | struct nfs_fh *root; | 615 | struct nfs_fh mntfh; |
| 968 | struct nfs_mount_data *data = raw_data; | 616 | struct nfs_mount_data *data = raw_data; |
| 617 | struct dentry *mntroot; | ||
| 618 | int error; | ||
| 969 | 619 | ||
| 970 | error = -EINVAL; | 620 | /* Validate the mount data */ |
| 971 | if (data == NULL) { | 621 | error = nfs_validate_mount_data(data, &mntfh); |
| 972 | dprintk("%s: missing data argument\n", __FUNCTION__); | 622 | if (error < 0) |
| 973 | goto out_err_noserver; | 623 | return error; |
| 974 | } | ||
| 975 | if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) { | ||
| 976 | dprintk("%s: bad mount version\n", __FUNCTION__); | ||
| 977 | goto out_err_noserver; | ||
| 978 | } | ||
| 979 | switch (data->version) { | ||
| 980 | case 1: | ||
| 981 | data->namlen = 0; | ||
| 982 | case 2: | ||
| 983 | data->bsize = 0; | ||
| 984 | case 3: | ||
| 985 | if (data->flags & NFS_MOUNT_VER3) { | ||
| 986 | dprintk("%s: mount structure version %d does not support NFSv3\n", | ||
| 987 | __FUNCTION__, | ||
| 988 | data->version); | ||
| 989 | goto out_err_noserver; | ||
| 990 | } | ||
| 991 | data->root.size = NFS2_FHSIZE; | ||
| 992 | memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); | ||
| 993 | case 4: | ||
| 994 | if (data->flags & NFS_MOUNT_SECFLAVOUR) { | ||
| 995 | dprintk("%s: mount structure version %d does not support strong security\n", | ||
| 996 | __FUNCTION__, | ||
| 997 | data->version); | ||
| 998 | goto out_err_noserver; | ||
| 999 | } | ||
| 1000 | case 5: | ||
| 1001 | memset(data->context, 0, sizeof(data->context)); | ||
| 1002 | } | ||
| 1003 | #ifndef CONFIG_NFS_V3 | ||
| 1004 | /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */ | ||
| 1005 | error = -EPROTONOSUPPORT; | ||
| 1006 | if (data->flags & NFS_MOUNT_VER3) { | ||
| 1007 | dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__); | ||
| 1008 | goto out_err_noserver; | ||
| 1009 | } | ||
| 1010 | #endif /* CONFIG_NFS_V3 */ | ||
| 1011 | 624 | ||
| 1012 | error = -ENOMEM; | 625 | /* Get a volume representation */ |
| 1013 | server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); | 626 | server = nfs_create_server(data, &mntfh); |
| 1014 | if (!server) | 627 | if (IS_ERR(server)) { |
| 628 | error = PTR_ERR(server); | ||
| 1015 | goto out_err_noserver; | 629 | goto out_err_noserver; |
| 1016 | /* Zero out the NFS state stuff */ | ||
| 1017 | init_nfsv4_state(server); | ||
| 1018 | server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); | ||
| 1019 | |||
| 1020 | root = &server->fh; | ||
| 1021 | if (data->flags & NFS_MOUNT_VER3) | ||
| 1022 | root->size = data->root.size; | ||
| 1023 | else | ||
| 1024 | root->size = NFS2_FHSIZE; | ||
| 1025 | error = -EINVAL; | ||
| 1026 | if (root->size > sizeof(root->data)) { | ||
| 1027 | dprintk("%s: invalid root filehandle\n", __FUNCTION__); | ||
| 1028 | goto out_err; | ||
| 1029 | } | ||
| 1030 | memcpy(root->data, data->root.data, root->size); | ||
| 1031 | |||
| 1032 | /* We now require that the mount process passes the remote address */ | ||
| 1033 | memcpy(&server->addr, &data->addr, sizeof(server->addr)); | ||
| 1034 | if (server->addr.sin_addr.s_addr == INADDR_ANY) { | ||
| 1035 | dprintk("%s: mount program didn't pass remote address!\n", | ||
| 1036 | __FUNCTION__); | ||
| 1037 | goto out_err; | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | /* Fire up rpciod if not yet running */ | ||
| 1041 | error = rpciod_up(); | ||
| 1042 | if (error < 0) { | ||
| 1043 | dprintk("%s: couldn't start rpciod! Error = %d\n", | ||
| 1044 | __FUNCTION__, error); | ||
| 1045 | goto out_err; | ||
| 1046 | } | 630 | } |
| 1047 | 631 | ||
| 632 | /* Get a superblock - note that we may end up sharing one that already exists */ | ||
| 1048 | s = sget(fs_type, nfs_compare_super, nfs_set_super, server); | 633 | s = sget(fs_type, nfs_compare_super, nfs_set_super, server); |
| 1049 | if (IS_ERR(s)) { | 634 | if (IS_ERR(s)) { |
| 1050 | error = PTR_ERR(s); | 635 | error = PTR_ERR(s); |
| 1051 | goto out_err_rpciod; | 636 | goto out_err_nosb; |
| 1052 | } | 637 | } |
| 1053 | 638 | ||
| 1054 | if (s->s_root) | 639 | if (s->s_fs_info != server) { |
| 1055 | goto out_rpciod_down; | 640 | nfs_free_server(server); |
| 641 | server = NULL; | ||
| 642 | } | ||
| 1056 | 643 | ||
| 1057 | s->s_flags = flags; | 644 | if (!s->s_root) { |
| 645 | /* initial superblock/root creation */ | ||
| 646 | s->s_flags = flags; | ||
| 647 | nfs_fill_super(s, data); | ||
| 648 | } | ||
| 1058 | 649 | ||
| 1059 | error = nfs_fill_super(s, data, flags & MS_SILENT ? 1 : 0); | 650 | mntroot = nfs_get_root(s, &mntfh); |
| 1060 | if (error) { | 651 | if (IS_ERR(mntroot)) { |
| 1061 | up_write(&s->s_umount); | 652 | error = PTR_ERR(mntroot); |
| 1062 | deactivate_super(s); | 653 | goto error_splat_super; |
| 1063 | return error; | ||
| 1064 | } | 654 | } |
| 1065 | s->s_flags |= MS_ACTIVE; | ||
| 1066 | return simple_set_mnt(mnt, s); | ||
| 1067 | 655 | ||
| 1068 | out_rpciod_down: | 656 | s->s_flags |= MS_ACTIVE; |
| 1069 | rpciod_down(); | 657 | mnt->mnt_sb = s; |
| 1070 | kfree(server); | 658 | mnt->mnt_root = mntroot; |
| 1071 | return simple_set_mnt(mnt, s); | 659 | return 0; |
| 1072 | 660 | ||
| 1073 | out_err_rpciod: | 661 | out_err_nosb: |
| 1074 | rpciod_down(); | 662 | nfs_free_server(server); |
| 1075 | out_err: | ||
| 1076 | kfree(server); | ||
| 1077 | out_err_noserver: | 663 | out_err_noserver: |
| 1078 | return error; | 664 | return error; |
| 665 | |||
| 666 | error_splat_super: | ||
| 667 | up_write(&s->s_umount); | ||
| 668 | deactivate_super(s); | ||
| 669 | return error; | ||
| 1079 | } | 670 | } |
| 1080 | 671 | ||
| 672 | /* | ||
| 673 | * Destroy an NFS2/3 superblock | ||
| 674 | */ | ||
| 1081 | static void nfs_kill_super(struct super_block *s) | 675 | static void nfs_kill_super(struct super_block *s) |
| 1082 | { | 676 | { |
| 1083 | struct nfs_server *server = NFS_SB(s); | 677 | struct nfs_server *server = NFS_SB(s); |
| 1084 | 678 | ||
| 1085 | kill_anon_super(s); | 679 | kill_anon_super(s); |
| 1086 | 680 | nfs_free_server(server); | |
| 1087 | if (!IS_ERR(server->client)) | ||
| 1088 | rpc_shutdown_client(server->client); | ||
| 1089 | if (!IS_ERR(server->client_sys)) | ||
| 1090 | rpc_shutdown_client(server->client_sys); | ||
| 1091 | if (!IS_ERR(server->client_acl)) | ||
| 1092 | rpc_shutdown_client(server->client_acl); | ||
| 1093 | |||
| 1094 | if (!(server->flags & NFS_MOUNT_NONLM)) | ||
| 1095 | lockd_down(); /* release rpc.lockd */ | ||
| 1096 | |||
| 1097 | rpciod_down(); /* release rpciod */ | ||
| 1098 | |||
| 1099 | nfs_free_iostats(server->io_stats); | ||
| 1100 | kfree(server->hostname); | ||
| 1101 | kfree(server); | ||
| 1102 | nfs_release_automount_timer(); | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | static struct super_block *nfs_clone_sb(struct nfs_server *server, struct nfs_clone_mount *data) | ||
| 1106 | { | ||
| 1107 | struct super_block *sb; | ||
| 1108 | |||
| 1109 | server->fsid = data->fattr->fsid; | ||
| 1110 | nfs_copy_fh(&server->fh, data->fh); | ||
| 1111 | sb = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server); | ||
| 1112 | if (!IS_ERR(sb) && sb->s_root == NULL && !(server->flags & NFS_MOUNT_NONLM)) | ||
| 1113 | lockd_up(); | ||
| 1114 | return sb; | ||
| 1115 | } | 681 | } |
| 1116 | 682 | ||
| 1117 | static int nfs_clone_nfs_sb(struct file_system_type *fs_type, | 683 | /* |
| 1118 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) | 684 | * Clone an NFS2/3 server record on xdev traversal (FSID-change) |
| 685 | */ | ||
| 686 | static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, | ||
| 687 | const char *dev_name, void *raw_data, | ||
| 688 | struct vfsmount *mnt) | ||
| 1119 | { | 689 | { |
| 1120 | struct nfs_clone_mount *data = raw_data; | 690 | struct nfs_clone_mount *data = raw_data; |
| 1121 | return nfs_clone_generic_sb(data, nfs_clone_sb, nfs_clone_server, mnt); | 691 | struct super_block *s; |
| 1122 | } | 692 | struct nfs_server *server; |
| 693 | struct dentry *mntroot; | ||
| 694 | int error; | ||
| 1123 | 695 | ||
| 1124 | #ifdef CONFIG_NFS_V4 | 696 | dprintk("--> nfs_xdev_get_sb()\n"); |
| 1125 | static struct rpc_clnt *nfs4_create_client(struct nfs_server *server, | ||
| 1126 | struct rpc_timeout *timeparms, int proto, rpc_authflavor_t flavor) | ||
| 1127 | { | ||
| 1128 | struct nfs4_client *clp; | ||
| 1129 | struct rpc_xprt *xprt = NULL; | ||
| 1130 | struct rpc_clnt *clnt = NULL; | ||
| 1131 | int err = -EIO; | ||
| 1132 | |||
| 1133 | clp = nfs4_get_client(&server->addr.sin_addr); | ||
| 1134 | if (!clp) { | ||
| 1135 | dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__); | ||
| 1136 | return ERR_PTR(err); | ||
| 1137 | } | ||
| 1138 | 697 | ||
| 1139 | /* Now create transport and client */ | 698 | /* create a new volume representation */ |
| 1140 | down_write(&clp->cl_sem); | 699 | server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr); |
| 1141 | if (IS_ERR(clp->cl_rpcclient)) { | 700 | if (IS_ERR(server)) { |
| 1142 | xprt = xprt_create_proto(proto, &server->addr, timeparms); | 701 | error = PTR_ERR(server); |
| 1143 | if (IS_ERR(xprt)) { | 702 | goto out_err_noserver; |
| 1144 | up_write(&clp->cl_sem); | ||
| 1145 | err = PTR_ERR(xprt); | ||
| 1146 | dprintk("%s: cannot create RPC transport. Error = %d\n", | ||
| 1147 | __FUNCTION__, err); | ||
| 1148 | goto out_fail; | ||
| 1149 | } | ||
| 1150 | /* Bind to a reserved port! */ | ||
| 1151 | xprt->resvport = 1; | ||
| 1152 | clnt = rpc_create_client(xprt, server->hostname, &nfs_program, | ||
| 1153 | server->rpc_ops->version, flavor); | ||
| 1154 | if (IS_ERR(clnt)) { | ||
| 1155 | up_write(&clp->cl_sem); | ||
| 1156 | err = PTR_ERR(clnt); | ||
| 1157 | dprintk("%s: cannot create RPC client. Error = %d\n", | ||
| 1158 | __FUNCTION__, err); | ||
| 1159 | goto out_fail; | ||
| 1160 | } | ||
| 1161 | clnt->cl_intr = 1; | ||
| 1162 | clnt->cl_softrtry = 1; | ||
| 1163 | clp->cl_rpcclient = clnt; | ||
| 1164 | memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr)); | ||
| 1165 | nfs_idmap_new(clp); | ||
| 1166 | } | ||
| 1167 | list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); | ||
| 1168 | clnt = rpc_clone_client(clp->cl_rpcclient); | ||
| 1169 | if (!IS_ERR(clnt)) | ||
| 1170 | server->nfs4_state = clp; | ||
| 1171 | up_write(&clp->cl_sem); | ||
| 1172 | clp = NULL; | ||
| 1173 | |||
| 1174 | if (IS_ERR(clnt)) { | ||
| 1175 | dprintk("%s: cannot create RPC client. Error = %d\n", | ||
| 1176 | __FUNCTION__, err); | ||
| 1177 | return clnt; | ||
| 1178 | } | 703 | } |
| 1179 | 704 | ||
| 1180 | if (server->nfs4_state->cl_idmap == NULL) { | 705 | /* Get a superblock - note that we may end up sharing one that already exists */ |
| 1181 | dprintk("%s: failed to create idmapper.\n", __FUNCTION__); | 706 | s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server); |
| 1182 | return ERR_PTR(-ENOMEM); | 707 | if (IS_ERR(s)) { |
| 708 | error = PTR_ERR(s); | ||
| 709 | goto out_err_nosb; | ||
| 1183 | } | 710 | } |
| 1184 | 711 | ||
| 1185 | if (clnt->cl_auth->au_flavor != flavor) { | 712 | if (s->s_fs_info != server) { |
| 1186 | struct rpc_auth *auth; | 713 | nfs_free_server(server); |
| 1187 | 714 | server = NULL; | |
| 1188 | auth = rpcauth_create(flavor, clnt); | ||
| 1189 | if (IS_ERR(auth)) { | ||
| 1190 | dprintk("%s: couldn't create credcache!\n", __FUNCTION__); | ||
| 1191 | return (struct rpc_clnt *)auth; | ||
| 1192 | } | ||
| 1193 | } | 715 | } |
| 1194 | return clnt; | ||
| 1195 | |||
| 1196 | out_fail: | ||
| 1197 | if (clp) | ||
| 1198 | nfs4_put_client(clp); | ||
| 1199 | return ERR_PTR(err); | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | /* | ||
| 1203 | * Set up an NFS4 superblock | ||
| 1204 | */ | ||
| 1205 | static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, int silent) | ||
| 1206 | { | ||
| 1207 | struct nfs_server *server; | ||
| 1208 | struct rpc_timeout timeparms; | ||
| 1209 | rpc_authflavor_t authflavour; | ||
| 1210 | int err = -EIO; | ||
| 1211 | 716 | ||
| 1212 | sb->s_blocksize_bits = 0; | 717 | if (!s->s_root) { |
| 1213 | sb->s_blocksize = 0; | 718 | /* initial superblock/root creation */ |
| 1214 | server = NFS_SB(sb); | 719 | s->s_flags = flags; |
| 1215 | if (data->rsize != 0) | 720 | nfs_clone_super(s, data->sb); |
| 1216 | server->rsize = nfs_block_size(data->rsize, NULL); | 721 | } |
| 1217 | if (data->wsize != 0) | ||
| 1218 | server->wsize = nfs_block_size(data->wsize, NULL); | ||
| 1219 | server->flags = data->flags & NFS_MOUNT_FLAGMASK; | ||
| 1220 | server->caps = NFS_CAP_ATOMIC_OPEN; | ||
| 1221 | 722 | ||
| 1222 | server->acregmin = data->acregmin*HZ; | 723 | mntroot = nfs_get_root(s, data->fh); |
| 1223 | server->acregmax = data->acregmax*HZ; | 724 | if (IS_ERR(mntroot)) { |
| 1224 | server->acdirmin = data->acdirmin*HZ; | 725 | error = PTR_ERR(mntroot); |
| 1225 | server->acdirmax = data->acdirmax*HZ; | 726 | goto error_splat_super; |
| 727 | } | ||
| 1226 | 728 | ||
| 1227 | server->rpc_ops = &nfs_v4_clientops; | 729 | s->s_flags |= MS_ACTIVE; |
| 730 | mnt->mnt_sb = s; | ||
| 731 | mnt->mnt_root = mntroot; | ||
| 1228 | 732 | ||
| 1229 | nfs_init_timeout_values(&timeparms, data->proto, data->timeo, data->retrans); | 733 | dprintk("<-- nfs_xdev_get_sb() = 0\n"); |
| 734 | return 0; | ||
| 1230 | 735 | ||
| 1231 | server->retrans_timeo = timeparms.to_initval; | 736 | out_err_nosb: |
| 1232 | server->retrans_count = timeparms.to_retries; | 737 | nfs_free_server(server); |
| 738 | out_err_noserver: | ||
| 739 | dprintk("<-- nfs_xdev_get_sb() = %d [error]\n", error); | ||
| 740 | return error; | ||
| 1233 | 741 | ||
| 1234 | /* Now create transport and client */ | 742 | error_splat_super: |
| 1235 | authflavour = RPC_AUTH_UNIX; | 743 | up_write(&s->s_umount); |
| 1236 | if (data->auth_flavourlen != 0) { | 744 | deactivate_super(s); |
| 1237 | if (data->auth_flavourlen != 1) { | 745 | dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error); |
| 1238 | dprintk("%s: Invalid number of RPC auth flavours %d.\n", | 746 | return error; |
| 1239 | __FUNCTION__, data->auth_flavourlen); | 747 | } |
| 1240 | err = -EINVAL; | ||
| 1241 | goto out_fail; | ||
| 1242 | } | ||
| 1243 | if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) { | ||
| 1244 | err = -EFAULT; | ||
| 1245 | goto out_fail; | ||
| 1246 | } | ||
| 1247 | } | ||
| 1248 | 748 | ||
| 1249 | server->client = nfs4_create_client(server, &timeparms, data->proto, authflavour); | 749 | #ifdef CONFIG_NFS_V4 |
| 1250 | if (IS_ERR(server->client)) { | ||
| 1251 | err = PTR_ERR(server->client); | ||
| 1252 | dprintk("%s: cannot create RPC client. Error = %d\n", | ||
| 1253 | __FUNCTION__, err); | ||
| 1254 | goto out_fail; | ||
| 1255 | } | ||
| 1256 | 750 | ||
| 751 | /* | ||
| 752 | * Finish setting up a cloned NFS4 superblock | ||
| 753 | */ | ||
| 754 | static void nfs4_clone_super(struct super_block *sb, | ||
| 755 | const struct super_block *old_sb) | ||
| 756 | { | ||
| 757 | sb->s_blocksize_bits = old_sb->s_blocksize_bits; | ||
| 758 | sb->s_blocksize = old_sb->s_blocksize; | ||
| 759 | sb->s_maxbytes = old_sb->s_maxbytes; | ||
| 1257 | sb->s_time_gran = 1; | 760 | sb->s_time_gran = 1; |
| 1258 | 761 | sb->s_op = old_sb->s_op; | |
| 1259 | sb->s_op = &nfs4_sops; | 762 | nfs_initialise_sb(sb); |
| 1260 | err = nfs_sb_init(sb, authflavour); | ||
| 1261 | |||
| 1262 | out_fail: | ||
| 1263 | return err; | ||
| 1264 | } | 763 | } |
| 1265 | 764 | ||
| 1266 | static int nfs4_compare_super(struct super_block *sb, void *data) | 765 | /* |
| 766 | * Set up an NFS4 superblock | ||
| 767 | */ | ||
| 768 | static void nfs4_fill_super(struct super_block *sb) | ||
| 1267 | { | 769 | { |
| 1268 | struct nfs_server *server = data; | 770 | sb->s_time_gran = 1; |
| 1269 | struct nfs_server *old = NFS_SB(sb); | 771 | sb->s_op = &nfs4_sops; |
| 1270 | 772 | nfs_initialise_sb(sb); | |
| 1271 | if (strcmp(server->hostname, old->hostname) != 0) | ||
| 1272 | return 0; | ||
| 1273 | if (strcmp(server->mnt_path, old->mnt_path) != 0) | ||
| 1274 | return 0; | ||
| 1275 | return 1; | ||
| 1276 | } | 773 | } |
| 1277 | 774 | ||
| 1278 | static void * | 775 | static void *nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen) |
| 1279 | nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen) | ||
| 1280 | { | 776 | { |
| 1281 | void *p = NULL; | 777 | void *p = NULL; |
| 1282 | 778 | ||
| @@ -1297,14 +793,22 @@ nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen) · 14 unmodified lines | |||
| 1297 | return dst; | 793 | return dst; |
| 1298 | } | 794 | } |
| 1299 | 795 | ||
| 796 | /* | ||
| 797 | * Get the superblock for an NFS4 mountpoint | ||
| 798 | */ | ||
| 1300 | static int nfs4_get_sb(struct file_system_type *fs_type, | 799 | static int nfs4_get_sb(struct file_system_type *fs_type, |
| 1301 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) | 800 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) |
| 1302 | { | 801 | { |
| 1303 | int error; | ||
| 1304 | struct nfs_server *server; | ||
| 1305 | struct super_block *s; | ||
| 1306 | struct nfs4_mount_data *data = raw_data; | 802 | struct nfs4_mount_data *data = raw_data; |
| 803 | struct super_block *s; | ||
| 804 | struct nfs_server *server; | ||
| 805 | struct sockaddr_in addr; | ||
| 806 | rpc_authflavor_t authflavour; | ||
| 807 | struct nfs_fh mntfh; | ||
| 808 | struct dentry *mntroot; | ||
| 809 | char *mntpath = NULL, *hostname = NULL, ip_addr[16]; | ||
| 1307 | void *p; | 810 | void *p; |
| 811 | int error; | ||
| 1308 | 812 | ||
| 1309 | if (data == NULL) { | 813 | if (data == NULL) { |
| 1310 | dprintk("%s: missing data argument\n", __FUNCTION__); | 814 | dprintk("%s: missing data argument\n", __FUNCTION__); |
| @@ -1315,84 +819,112 @@ static int nfs4_get_sb(struct file_system_type *fs_type, · 4 unmodified lines | |||
| 1315 | return -EINVAL; | 819 | return -EINVAL; |
| 1316 | } | 820 | } |
| 1317 | 821 | ||
| 1318 | server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); | 822 | /* We now require that the mount process passes the remote address */ |
| 1319 | if (!server) | 823 | if (data->host_addrlen != sizeof(addr)) |
| 1320 | return -ENOMEM; | 824 | return -EINVAL; |
| 1321 | /* Zero out the NFS state stuff */ | 825 | |
| 1322 | init_nfsv4_state(server); | 826 | if (copy_from_user(&addr, data->host_addr, sizeof(addr))) |
| 1323 | server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); | 827 | return -EFAULT; |
| 828 | |||
| 829 | if (addr.sin_family != AF_INET || | ||
| 830 | addr.sin_addr.s_addr == INADDR_ANY | ||
| 831 | ) { | ||
| 832 | dprintk("%s: mount program didn't pass remote IP address!\n", | ||
| 833 | __FUNCTION__); | ||
| 834 | return -EINVAL; | ||
| 835 | } | ||
| 836 | /* RFC3530: The default port for NFS is 2049 */ | ||
| 837 | if (addr.sin_port == 0) | ||
| 838 | addr.sin_port = NFS_PORT; | ||
| 839 | |||
| 840 | /* Grab the authentication type */ | ||
| 841 | authflavour = RPC_AUTH_UNIX; | ||
| 842 | if (data->auth_flavourlen != 0) { | ||
| 843 | if (data->auth_flavourlen != 1) { | ||
| 844 | dprintk("%s: Invalid number of RPC auth flavours %d.\n", | ||
| 845 | __FUNCTION__, data->auth_flavourlen); | ||
| 846 | error = -EINVAL; | ||
| 847 | goto out_err_noserver; | ||
| 848 | } | ||
| 849 | |||
| 850 | if (copy_from_user(&authflavour, data->auth_flavours, | ||
| 851 | sizeof(authflavour))) { | ||
| 852 | error = -EFAULT; | ||
| 853 | goto out_err_noserver; | ||
| 854 | } | ||
| 855 | } | ||
| 1324 | 856 | ||
| 1325 | p = nfs_copy_user_string(NULL, &data->hostname, 256); | 857 | p = nfs_copy_user_string(NULL, &data->hostname, 256); |
| 1326 | if (IS_ERR(p)) | 858 | if (IS_ERR(p)) |
| 1327 | goto out_err; | 859 | goto out_err; |
| 1328 | server->hostname = p; | 860 | hostname = p; |
| 1329 | 861 | ||
| 1330 | p = nfs_copy_user_string(NULL, &data->mnt_path, 1024); | 862 | p = nfs_copy_user_string(NULL, &data->mnt_path, 1024); |
| 1331 | if (IS_ERR(p)) | 863 | if (IS_ERR(p)) |
| 1332 | goto out_err; | 864 | goto out_err; |
| 1333 | server->mnt_path = p; | 865 | mntpath = p; |
| 866 | |||
| 867 | dprintk("MNTPATH: %s\n", mntpath); | ||
| 1334 | 868 | ||
| 1335 | p = nfs_copy_user_string(server->ip_addr, &data->client_addr, | 869 | p = nfs_copy_user_string(ip_addr, &data->client_addr, |
| 1336 | sizeof(server->ip_addr) - 1); | 870 | sizeof(ip_addr) - 1); |
| 1337 | if (IS_ERR(p)) | 871 | if (IS_ERR(p)) |
| 1338 | goto out_err; | 872 | goto out_err; |
| 1339 | 873 | ||
| 1340 | /* We now require that the mount process passes the remote address */ | 874 | /* Get a volume representation */ |
| 1341 | if (data->host_addrlen != sizeof(server->addr)) { | 875 | server = nfs4_create_server(data, hostname, &addr, mntpath, ip_addr, |
| 1342 | error = -EINVAL; | 876 | authflavour, &mntfh); |
| 1343 | goto out_free; | 877 | if (IS_ERR(server)) { |
| 1344 | } | 878 | error = PTR_ERR(server); |
| 1345 | if (copy_from_user(&server->addr, data->host_addr, sizeof(server->addr))) { | 879 | goto out_err_noserver; |
| 1346 | error = -EFAULT; | ||
| 1347 | goto out_free; | ||
| 1348 | } | ||
| 1349 | if (server->addr.sin_family != AF_INET || | ||
| 1350 | server->addr.sin_addr.s_addr == INADDR_ANY) { | ||
| 1351 | dprintk("%s: mount program didn't pass remote IP address!\n", | ||
| 1352 | __FUNCTION__); | ||
| 1353 | error = -EINVAL; | ||
| 1354 | goto out_free; | ||
| 1355 | } | ||
| 1356 | |||
| 1357 | /* Fire up rpciod if not yet running */ | ||
| 1358 | error = rpciod_up(); | ||
| 1359 | if (error < 0) { | ||
| 1360 | dprintk("%s: couldn't start rpciod! Error = %d\n", | ||
| 1361 | __FUNCTION__, error); | ||
| 1362 | goto out_free; | ||
| 1363 | } | 880 | } |
| 1364 | 881 | ||
| 1365 | s = sget(fs_type, nfs4_compare_super, nfs_set_super, server); | 882 | /* Get a superblock - note that we may end up sharing one that already exists */ |
| 1366 | 883 | s = sget(fs_type, nfs_compare_super, nfs_set_super, server); | |
| 1367 | if (IS_ERR(s)) { | 884 | if (IS_ERR(s)) { |
| 1368 | error = PTR_ERR(s); | 885 | error = PTR_ERR(s); |
| 1369 | goto out_free; | 886 | goto out_free; |
| 1370 | } | 887 | } |
| 1371 | 888 | ||
| 1372 | if (s->s_root) { | 889 | if (s->s_fs_info != server) { |
| 1373 | kfree(server->mnt_path); | 890 | nfs_free_server(server); |
| 1374 | kfree(server->hostname); | 891 | server = NULL; |
| 1375 | kfree(server); | ||
| 1376 | return simple_set_mnt(mnt, s); | ||
| 1377 | } | 892 | } |
| 1378 | 893 | ||
| 1379 | s->s_flags = flags; | 894 | if (!s->s_root) { |
| 895 | /* initial superblock/root creation */ | ||
| 896 | s->s_flags = flags; | ||
| 897 | nfs4_fill_super(s); | ||
| 898 | } | ||
| 1380 | 899 | ||
| 1381 | error = nfs4_fill_super(s, data, flags & MS_SILENT ? 1 : 0); | 900 | mntroot = nfs4_get_root(s, &mntfh); |
| 1382 | if (error) { | 901 | if (IS_ERR(mntroot)) { |
| 1383 | up_write(&s->s_umount); | 902 | error = PTR_ERR(mntroot); |
| 1384 | deactivate_super(s); | 903 | goto error_splat_super; |
| 1385 | return error; | ||
| 1386 | } | 904 | } |
| 905 | |||
| 1387 | s->s_flags |= MS_ACTIVE; | 906 | s->s_flags |= MS_ACTIVE; |
| 1388 | return simple_set_mnt(mnt, s); | 907 | mnt->mnt_sb = s; |
| 908 | mnt->mnt_root = mntroot; | ||
| 909 | kfree(mntpath); | ||
| 910 | kfree(hostname); | ||
| 911 | return 0; | ||
| 912 | |||
| 1389 | out_err: | 913 | out_err: |
| 1390 | error = PTR_ERR(p); | 914 | error = PTR_ERR(p); |
| 915 | goto out_err_noserver; | ||
| 916 | |||
| 1391 | out_free: | 917 | out_free: |
| 1392 | kfree(server->mnt_path); | 918 | nfs_free_server(server); |
| 1393 | kfree(server->hostname); | 919 | out_err_noserver: |
| 1394 | kfree(server); | 920 | kfree(mntpath); |
| 921 | kfree(hostname); | ||
| 1395 | return error; | 922 | return error; |
| 923 | |||
| 924 | error_splat_super: | ||
| 925 | up_write(&s->s_umount); | ||
| 926 | deactivate_super(s); | ||
| 927 | goto out_err_noserver; | ||
| 1396 | } | 928 | } |
| 1397 | 929 | ||
| 1398 | static void nfs4_kill_super(struct super_block *sb) | 930 | static void nfs4_kill_super(struct super_block *sb) |
| @@ -1403,135 +935,140 @@ static void nfs4_kill_super(struct super_block *sb) · 4 unmodified lines | |||
| 1403 | kill_anon_super(sb); | 935 | kill_anon_super(sb); |
| 1404 | 936 | ||
| 1405 | nfs4_renewd_prepare_shutdown(server); | 937 | nfs4_renewd_prepare_shutdown(server); |
| 938 | nfs_free_server(server); | ||
| 939 | } | ||
| 940 | |||
| 941 | /* | ||
| 942 | * Clone an NFS4 server record on xdev traversal (FSID-change) | ||
| 943 | */ | ||
| 944 | static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, | ||
| 945 | const char *dev_name, void *raw_data, | ||
| 946 | struct vfsmount *mnt) | ||
| 947 | { | ||
| 948 | struct nfs_clone_mount *data = raw_data; | ||
| 949 | struct super_block *s; | ||
| 950 | struct nfs_server *server; | ||
| 951 | struct dentry *mntroot; | ||
| 952 | int error; | ||
| 953 | |||
| 954 | dprintk("--> nfs4_xdev_get_sb()\n"); | ||
| 955 | |||
| 956 | /* create a new volume representation */ | ||
| 957 | server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr); | ||
| 958 | if (IS_ERR(server)) { | ||
| 959 | error = PTR_ERR(server); | ||
| 960 | goto out_err_noserver; | ||
| 961 | } | ||
| 962 | |||
| 963 | /* Get a superblock - note that we may end up sharing one that already exists */ | ||
| 964 | s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server); | ||
| 965 | if (IS_ERR(s)) { | ||
| 966 | error = PTR_ERR(s); | ||
| 967 | goto out_err_nosb; | ||
| 968 | } | ||
| 1406 | 969 | ||
| 1407 | if (server->client != NULL && !IS_ERR(server->client)) | 970 | if (s->s_fs_info != server) { |
| 1408 | rpc_shutdown_client(server->client); | 971 | nfs_free_server(server); |
| 972 | server = NULL; | ||
| 973 | } | ||
| 1409 | 974 | ||
| 1410 | destroy_nfsv4_state(server); | 975 | if (!s->s_root) { |
| 976 | /* initial superblock/root creation */ | ||
| 977 | s->s_flags = flags; | ||
| 978 | nfs4_clone_super(s, data->sb); | ||
| 979 | } | ||
| 980 | |||
| 981 | mntroot = nfs4_get_root(s, data->fh); | ||
| 982 | if (IS_ERR(mntroot)) { | ||
| 983 | error = PTR_ERR(mntroot); | ||
| 984 | goto error_splat_super; | ||
| 985 | } | ||
| 1411 | 986 | ||
| 1412 | rpciod_down(); | 987 | s->s_flags |= MS_ACTIVE; |
| 988 | mnt->mnt_sb = s; | ||
| 989 | mnt->mnt_root = mntroot; | ||
| 990 | |||
| 991 | dprintk("<-- nfs4_xdev_get_sb() = 0\n"); | ||
| 992 | return 0; | ||
| 993 | |||
| 994 | out_err_nosb: | ||
| 995 | nfs_free_server(server); | ||
| 996 | out_err_noserver: | ||
| 997 | dprintk("<-- nfs4_xdev_get_sb() = %d [error]\n", error); | ||
| 998 | return error; | ||
| 1413 | 999 | ||
| 1414 | nfs_free_iostats(server->io_stats); | 1000 | error_splat_super: |
| 1415 | kfree(server->hostname); | 1001 | up_write(&s->s_umount); |
| 1416 | kfree(server); | 1002 | deactivate_super(s); |
| 1417 | nfs_release_automount_timer(); | 1003 | dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error); |
| 1004 | return error; | ||
| 1418 | } | 1005 | } |
| 1419 | 1006 | ||
| 1420 | /* | 1007 | /* |
| 1421 | * Constructs the SERVER-side path | 1008 | * Create an NFS4 server record on referral traversal |
| 1422 | */ | 1009 | */ |
| 1423 | static inline char *nfs4_dup_path(const struct dentry *dentry) | 1010 | static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags, |
| 1011 | const char *dev_name, void *raw_data, | ||
| 1012 | struct vfsmount *mnt) | ||
| 1424 | { | 1013 | { |
| 1425 | char *page = (char *) __get_free_page(GFP_USER); | 1014 | struct nfs_clone_mount *data = raw_data; |
| 1426 | char *path; | 1015 | struct super_block *s; |
| 1016 | struct nfs_server *server; | ||
| 1017 | struct dentry *mntroot; | ||
| 1018 | struct nfs_fh mntfh; | ||
| 1019 | int error; | ||
| 1427 | 1020 | ||
| 1428 | path = nfs4_path(dentry, page, PAGE_SIZE); | 1021 | dprintk("--> nfs4_referral_get_sb()\n"); |
| 1429 | if (!IS_ERR(path)) { | ||
| 1430 | int len = PAGE_SIZE + page - path; | ||
| 1431 | char *tmp = path; | ||
| 1432 | 1022 | ||
| 1433 | path = kmalloc(len, GFP_KERNEL); | 1023 | /* create a new volume representation */ |
| 1434 | if (path) | 1024 | server = nfs4_create_referral_server(data, &mntfh); |
| 1435 | memcpy(path, tmp, len); | 1025 | if (IS_ERR(server)) { |
| 1436 | else | 1026 | error = PTR_ERR(server); |
| 1437 | path = ERR_PTR(-ENOMEM); | 1027 | goto out_err_noserver; |
| 1438 | } | 1028 | } |
| 1439 | free_page((unsigned long)page); | ||
| 1440 | return path; | ||
| 1441 | } | ||
| 1442 | 1029 | ||
| 1443 | static struct super_block *nfs4_clone_sb(struct nfs_server *server, struct nfs_clone_mount *data) | 1030 | /* Get a superblock - note that we may end up sharing one that already exists */ |
| 1444 | { | 1031 | s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server); |
| 1445 | const struct dentry *dentry = data->dentry; | 1032 | if (IS_ERR(s)) { |
| 1446 | struct nfs4_client *clp = server->nfs4_state; | 1033 | error = PTR_ERR(s); |
| 1447 | struct super_block *sb; | 1034 | goto out_err_nosb; |
| 1448 | |||
| 1449 | server->fsid = data->fattr->fsid; | ||
| 1450 | nfs_copy_fh(&server->fh, data->fh); | ||
| 1451 | server->mnt_path = nfs4_dup_path(dentry); | ||
| 1452 | if (IS_ERR(server->mnt_path)) { | ||
| 1453 | sb = (struct super_block *)server->mnt_path; | ||
| 1454 | goto err; | ||
| 1455 | } | 1035 | } |
| 1456 | sb = sget(&nfs4_fs_type, nfs4_compare_super, nfs_set_super, server); | ||
| 1457 | if (IS_ERR(sb) || sb->s_root) | ||
| 1458 | goto free_path; | ||
| 1459 | nfs4_server_capabilities(server, &server->fh); | ||
| 1460 | |||
| 1461 | down_write(&clp->cl_sem); | ||
| 1462 | atomic_inc(&clp->cl_count); | ||
| 1463 | list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); | ||
| 1464 | up_write(&clp->cl_sem); | ||
| 1465 | return sb; | ||
| 1466 | free_path: | ||
| 1467 | kfree(server->mnt_path); | ||
| 1468 | err: | ||
| 1469 | server->mnt_path = NULL; | ||
| 1470 | return sb; | ||
| 1471 | } | ||
| 1472 | 1036 | ||
| 1473 | static int nfs_clone_nfs4_sb(struct file_system_type *fs_type, | 1037 | if (s->s_fs_info != server) { |
| 1474 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) | 1038 | nfs_free_server(server); |
| 1475 | { | 1039 | server = NULL; |
| 1476 | struct nfs_clone_mount *data = raw_data; | 1040 | } |
| 1477 | return nfs_clone_generic_sb(data, nfs4_clone_sb, nfs_clone_server, mnt); | ||
| 1478 | } | ||
| 1479 | 1041 | ||
| 1480 | static struct super_block *nfs4_referral_sb(struct nfs_server *server, struct nfs_clone_mount *data) | 1042 | if (!s->s_root) { |
| 1481 | { | 1043 | /* initial superblock/root creation */ |
| 1482 | struct super_block *sb = ERR_PTR(-ENOMEM); | 1044 | s->s_flags = flags; |
| 1483 | int len; | 1045 | nfs4_fill_super(s); |
| 1484 | 1046 | } | |
| 1485 | len = strlen(data->mnt_path) + 1; | ||
| 1486 | server->mnt_path = kmalloc(len, GFP_KERNEL); | ||
| 1487 | if (server->mnt_path == NULL) | ||
| 1488 | goto err; | ||
| 1489 | memcpy(server->mnt_path, data->mnt_path, len); | ||
| 1490 | memcpy(&server->addr, data->addr, sizeof(struct sockaddr_in)); | ||
| 1491 | |||
| 1492 | sb = sget(&nfs4_fs_type, nfs4_compare_super, nfs_set_super, server); | ||
| 1493 | if (IS_ERR(sb) || sb->s_root) | ||
| 1494 | goto free_path; | ||
| 1495 | return sb; | ||
| 1496 | free_path: | ||
| 1497 | kfree(server->mnt_path); | ||
| 1498 | err: | ||
| 1499 | server->mnt_path = NULL; | ||
| 1500 | return sb; | ||
| 1501 | } | ||
| 1502 | 1047 | ||
| 1503 | static struct nfs_server *nfs4_referral_server(struct super_block *sb, struct nfs_clone_mount *data) | 1048 | mntroot = nfs4_get_root(s, data->fh); |
| 1504 | { | 1049 | if (IS_ERR(mntroot)) { |
| 1505 | struct nfs_server *server = NFS_SB(sb); | 1050 | error = PTR_ERR(mntroot); |
| 1506 | struct rpc_timeout timeparms; | 1051 | goto error_splat_super; |
| 1507 | int proto, timeo, retrans; | 1052 | } |
| 1508 | void *err; | ||
| 1509 | |||
| 1510 | proto = IPPROTO_TCP; | ||
| 1511 | /* Since we are following a referral and there may be alternatives, | ||
| 1512 | set the timeouts and retries to low values */ | ||
| 1513 | timeo = 2; | ||
| 1514 | retrans = 1; | ||
| 1515 | nfs_init_timeout_values(&timeparms, proto, timeo, retrans); | ||
| 1516 | |||
| 1517 | server->client = nfs4_create_client(server, &timeparms, proto, data->authflavor); | ||
| 1518 | if (IS_ERR((err = server->client))) | ||
| 1519 | goto out_err; | ||
| 1520 | 1053 | ||
| 1521 | sb->s_time_gran = 1; | 1054 | s->s_flags |= MS_ACTIVE; |
| 1522 | sb->s_op = &nfs4_sops; | 1055 | mnt->mnt_sb = s; |
| 1523 | err = ERR_PTR(nfs_sb_init(sb, data->authflavor)); | 1056 | mnt->mnt_root = mntroot; |
| 1524 | if (!IS_ERR(err)) | ||
| 1525 | return server; | ||
| 1526 | out_err: | ||
| 1527 | return (struct nfs_server *)err; | ||
| 1528 | } | ||
| 1529 | 1057 | ||
| 1530 | static int nfs_referral_nfs4_sb(struct file_system_type *fs_type, | 1058 | dprintk("<-- nfs4_referral_get_sb() = 0\n"); |
| 1531 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) | 1059 | return 0; |
| 1532 | { | 1060 | |
| 1533 | struct nfs_clone_mount *data = raw_data; | 1061 | out_err_nosb: |
| 1534 | return nfs_clone_generic_sb(data, nfs4_referral_sb, nfs4_referral_server, mnt); | 1062 | nfs_free_server(server); |
| 1063 | out_err_noserver: | ||
| 1064 | dprintk("<-- nfs4_referral_get_sb() = %d [error]\n", error); | ||
| 1065 | return error; | ||
| 1066 | |||
| 1067 | error_splat_super: | ||
| 1068 | up_write(&s->s_umount); | ||
| 1069 | deactivate_super(s); | ||
| 1070 | dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error); | ||
| 1071 | return error; | ||
| 1535 | } | 1072 | } |
| 1536 | 1073 | ||
| 1537 | #endif | 1074 | #endif /* CONFIG_NFS_V4 */ |
| @@ -396,6 +396,7 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) · 395 unmodified lines | |||
| 396 | out: | 396 | out: |
| 397 | clear_bit(BDI_write_congested, &bdi->state); | 397 | clear_bit(BDI_write_congested, &bdi->state); |
| 398 | wake_up_all(&nfs_write_congestion); | 398 | wake_up_all(&nfs_write_congestion); |
| 399 | writeback_congestion_end(); | ||
| 399 | return err; | 400 | return err; |
| 400 | } | 401 | } |
| 401 | 402 | ||
| @@ -1252,7 +1253,13 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data) · 850 unmodified lines | |||
| 1252 | dprintk("NFS: %4d nfs_writeback_done (status %d)\n", | 1253 | dprintk("NFS: %4d nfs_writeback_done (status %d)\n", |
| 1253 | task->tk_pid, task->tk_status); | 1254 | task->tk_pid, task->tk_status); |
| 1254 | 1255 | ||
| 1255 | /* Call the NFS version-specific code */ | 1256 | /* |
| 1257 | * ->write_done will attempt to use post-op attributes to detect | ||
| 1258 | * conflicting writes by other clients. A strict interpretation | ||
| 1259 | * of close-to-open would allow us to continue caching even if | ||
| 1260 | * another writer had changed the file, but some applications | ||
| 1261 | * depend on tighter cache coherency when writing. | ||
| 1262 | */ | ||
| 1256 | status = NFS_PROTO(data->inode)->write_done(task, data); | 1263 | status = NFS_PROTO(data->inode)->write_done(task, data); |
| 1257 | if (status != 0) | 1264 | if (status != 0) |
| 1258 | return status; | 1265 | return status; |
| @@ -1273,7 +1280,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data) · 14 unmodified lines | |||
| 1273 | if (time_before(complain, jiffies)) { | 1280 | if (time_before(complain, jiffies)) { |
| 1274 | dprintk("NFS: faulty NFS server %s:" | 1281 | dprintk("NFS: faulty NFS server %s:" |
| 1275 | " (committed = %d) != (stable = %d)\n", | 1282 | " (committed = %d) != (stable = %d)\n", |
| 1276 | NFS_SERVER(data->inode)->hostname, | 1283 | NFS_SERVER(data->inode)->nfs_client->cl_hostname, |
| 1277 | resp->verf->committed, argp->stable); | 1284 | resp->verf->committed, argp->stable); |
| 1278 | complain = jiffies + 300 * HZ; | 1285 | complain = jiffies + 300 * HZ; |
| 1279 | } | 1286 | } |
| @@ -375,16 +375,28 @@ nfsd4_probe_callback(struct nfs4_client *clp) · 374 unmodified lines | |||
| 375 | { | 375 | { |
| 376 | struct sockaddr_in addr; | 376 | struct sockaddr_in addr; |
| 377 | struct nfs4_callback *cb = &clp->cl_callback; | 377 | struct nfs4_callback *cb = &clp->cl_callback; |
| 378 | struct rpc_timeout timeparms; | 378 | struct rpc_timeout timeparms = { |
| 379 | struct rpc_xprt * xprt; | 379 | .to_initval = (NFSD_LEASE_TIME/4) * HZ, |
| 380 | .to_retries = 5, | ||
| 381 | .to_maxval = (NFSD_LEASE_TIME/2) * HZ, | ||
| 382 | .to_exponential = 1, | ||
| 383 | }; | ||
| 380 | struct rpc_program * program = &cb->cb_program; | 384 | struct rpc_program * program = &cb->cb_program; |
| 381 | struct rpc_stat * stat = &cb->cb_stat; | 385 | struct rpc_create_args args = { |
| 382 | struct rpc_clnt * clnt; | 386 | .protocol = IPPROTO_TCP, |
| 387 | .address = (struct sockaddr *)&addr, | ||
| 388 | .addrsize = sizeof(addr), | ||
| 389 | .timeout = &timeparms, | ||
| 390 | .servername = clp->cl_name.data, | ||
| 391 | .program = program, | ||
| 392 | .version = nfs_cb_version[1]->number, | ||
| 393 | .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ | ||
| 394 | .flags = (RPC_CLNT_CREATE_NOPING), | ||
| 395 | }; | ||
| 383 | struct rpc_message msg = { | 396 | struct rpc_message msg = { |
| 384 | .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], | 397 | .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], |
| 385 | .rpc_argp = clp, | 398 | .rpc_argp = clp, |
| 386 | }; | 399 | }; |
| 387 | char hostname[32]; | ||
| 388 | int status; | 400 | int status; |
| 389 | 401 | ||
| 390 | if (atomic_read(&cb->cb_set)) | 402 | if (atomic_read(&cb->cb_set)) |
| @@ -396,51 +408,27 @@ nfsd4_probe_callback(struct nfs4_client *clp) · 5 unmodified lines | |||
| 396 | addr.sin_port = htons(cb->cb_port); | 408 | addr.sin_port = htons(cb->cb_port); |
| 397 | addr.sin_addr.s_addr = htonl(cb->cb_addr); | 409 | addr.sin_addr.s_addr = htonl(cb->cb_addr); |
| 398 | 410 | ||
| 399 | /* Initialize timeout */ | ||
| 400 | timeparms.to_initval = (NFSD_LEASE_TIME/4) * HZ; | ||
| 401 | timeparms.to_retries = 0; | ||
| 402 | timeparms.to_maxval = (NFSD_LEASE_TIME/2) * HZ; | ||
| 403 | timeparms.to_exponential = 1; | ||
| 404 | |||
| 405 | /* Create RPC transport */ | ||
| 406 | xprt = xprt_create_proto(IPPROTO_TCP, &addr, &timeparms); | ||
| 407 | if (IS_ERR(xprt)) { | ||
| 408 | dprintk("NFSD: couldn't create callback transport!\n"); | ||
| 409 | goto out_err; | ||
| 410 | } | ||
| 411 | |||
| 412 | /* Initialize rpc_program */ | 411 | /* Initialize rpc_program */ |
| 413 | program->name = "nfs4_cb"; | 412 | program->name = "nfs4_cb"; |
| 414 | program->number = cb->cb_prog; | 413 | program->number = cb->cb_prog; |
| 415 | program->nrvers = ARRAY_SIZE(nfs_cb_version); | 414 | program->nrvers = ARRAY_SIZE(nfs_cb_version); |
| 416 | program->version = nfs_cb_version; | 415 | program->version = nfs_cb_version; |
| 417 | program->stats = stat; | 416 | program->stats = &cb->cb_stat; |
| 418 | 417 | ||
| 419 | /* Initialize rpc_stat */ | 418 | /* Initialize rpc_stat */ |
| 420 | memset(stat, 0, sizeof(struct rpc_stat)); | 419 | memset(program->stats, 0, sizeof(cb->cb_stat)); |
| 421 | stat->program = program; | 420 | program->stats->program = program; |
| 422 | 421 | ||
| 423 | /* Create RPC client | 422 | /* Create RPC client */ |
| 424 | * | 423 | cb->cb_client = rpc_create(&args); |
| 425 | * XXX AUTH_UNIX only - need AUTH_GSS.... | 424 | if (!cb->cb_client) { |
| 426 | */ | ||
| 427 | sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr)); | ||
| 428 | clnt = rpc_new_client(xprt, hostname, program, 1, RPC_AUTH_UNIX); | ||
| 429 | if (IS_ERR(clnt)) { | ||
| 430 | dprintk("NFSD: couldn't create callback client\n"); | 425 | dprintk("NFSD: couldn't create callback client\n"); |
| 431 | goto out_err; | 426 | goto out_err; |
| 432 | } | 427 | } |
| 433 | clnt->cl_intr = 0; | ||
| 434 | clnt->cl_softrtry = 1; | ||
| 435 | 428 | ||
| 436 | /* Kick rpciod, put the call on the wire. */ | 429 | /* Kick rpciod, put the call on the wire. */ |
| 437 | 430 | if (rpciod_up() != 0) | |
| 438 | if (rpciod_up() != 0) { | ||
| 439 | dprintk("nfsd: couldn't start rpciod for callbacks!\n"); | ||
| 440 | goto out_clnt; | 431 | goto out_clnt; |
| 441 | } | ||
| 442 | |||
| 443 | cb->cb_client = clnt; | ||
| 444 | 432 | ||
| 445 | /* the task holds a reference to the nfs4_client struct */ | 433 | /* the task holds a reference to the nfs4_client struct */ |
| 446 | atomic_inc(&clp->cl_count); | 434 | atomic_inc(&clp->cl_count); |
| @@ -448,7 +436,7 @@ nfsd4_probe_callback(struct nfs4_client *clp) · 1 unmodified line | |||
| 448 | msg.rpc_cred = nfsd4_lookupcred(clp,0); | 436 | msg.rpc_cred = nfsd4_lookupcred(clp,0); |
| 449 | if (IS_ERR(msg.rpc_cred)) | 437 | if (IS_ERR(msg.rpc_cred)) |
| 450 | goto out_rpciod; | 438 | goto out_rpciod; |
| 451 | status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, &nfs4_cb_null_ops, NULL); | 439 | status = rpc_call_async(cb->cb_client, &msg, RPC_TASK_ASYNC, &nfs4_cb_null_ops, NULL); |
| 452 | put_rpccred(msg.rpc_cred); | 440 | put_rpccred(msg.rpc_cred); |
| 453 | 441 | ||
| 454 | if (status != 0) { | 442 | if (status != 0) { |
| @@ -462,7 +450,7 @@ out_rpciod: · 7 unmodified lines | |||
| 462 | rpciod_down(); | 450 | rpciod_down(); |
| 463 | cb->cb_client = NULL; | 451 | cb->cb_client = NULL; |
| 464 | out_clnt: | 452 | out_clnt: |
| 465 | rpc_shutdown_client(clnt); | 453 | rpc_shutdown_client(cb->cb_client); |
| 466 | out_err: | 454 | out_err: |
| 467 | dprintk("NFSD: warning: no callback path to client %.*s\n", | 455 | dprintk("NFSD: warning: no callback path to client %.*s\n", |
| 468 | (int)clp->cl_name.len, clp->cl_name.data); | 456 | (int)clp->cl_name.len, clp->cl_name.data); |
| @@ -86,7 +86,7 @@ void ppc4xx_init(unsigned long r3, unsigned long r4, unsigned long r5, · 85 unmodified lines | |||
| 86 | #define PCI_DRAM_OFFSET 0 | 86 | #define PCI_DRAM_OFFSET 0 |
| 87 | #endif | 87 | #endif |
| 88 | 88 | ||
| 89 | #elif CONFIG_44x | 89 | #elif defined(CONFIG_44x) |
| 90 | 90 | ||
| 91 | #if defined(CONFIG_BAMBOO) | 91 | #if defined(CONFIG_BAMBOO) |
| 92 | #include <platforms/4xx/bamboo.h> | 92 | #include <platforms/4xx/bamboo.h> |
| @@ -748,6 +748,7 @@ extern void blk_queue_invalidate_tags(request_queue_t *); · 747 unmodified lines | |||
| 748 | extern long blk_congestion_wait(int rw, long timeout); | 748 | extern long blk_congestion_wait(int rw, long timeout); |
| 749 | extern struct blk_queue_tag *blk_init_tags(int); | 749 | extern struct blk_queue_tag *blk_init_tags(int); |
| 750 | extern void blk_free_tags(struct blk_queue_tag *); | 750 | extern void blk_free_tags(struct blk_queue_tag *); |
| 751 | extern void blk_congestion_end(int rw); | ||
| 751 | 752 | ||
| 752 | extern void blk_rq_bio_prep(request_queue_t *, struct request *, struct bio *); | 753 | extern void blk_rq_bio_prep(request_queue_t *, struct request *, struct bio *); |
| 753 | extern int blkdev_issue_flush(struct block_device *, sector_t *); | 754 | extern int blkdev_issue_flush(struct block_device *, sector_t *); |
| @@ -114,7 +114,7 @@ extern void *__init alloc_large_system_hash(const char *tablename, · 113 unmodified lines | |||
| 114 | #else | 114 | #else |
| 115 | #define HASHDIST_DEFAULT 0 | 115 | #define HASHDIST_DEFAULT 0 |
| 116 | #endif | 116 | #endif |
| 117 | extern int __initdata hashdist; /* Distribute hashes across NUMA nodes? */ | 117 | extern int hashdist; /* Distribute hashes across NUMA nodes? */ |
| 118 | 118 | ||
| 119 | 119 | ||
| 120 | #endif /* _LINUX_BOOTMEM_H */ | 120 | #endif /* _LINUX_BOOTMEM_H */ |
| @@ -221,6 +221,7 @@ static inline int dname_external(struct dentry *dentry) · 220 unmodified lines | |||
| 221 | */ | 221 | */ |
| 222 | extern void d_instantiate(struct dentry *, struct inode *); | 222 | extern void d_instantiate(struct dentry *, struct inode *); |
| 223 | extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *); | 223 | extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *); |
| 224 | extern struct dentry * d_materialise_unique(struct dentry *, struct inode *); | ||
| 224 | extern void d_delete(struct dentry *); | 225 | extern void d_delete(struct dentry *); |
| 225 | 226 | ||
| 226 | /* allocate/de-allocate */ | 227 | /* allocate/de-allocate */ |
| @@ -438,6 +438,7 @@ struct dccp_ackvec; · 437 unmodified lines | |||
| 438 | * @dccps_role - Role of this sock, one of %dccp_role | 438 | * @dccps_role - Role of this sock, one of %dccp_role |
| 439 | * @dccps_ndp_count - number of Non Data Packets since last data packet | 439 | * @dccps_ndp_count - number of Non Data Packets since last data packet |
| 440 | * @dccps_hc_rx_ackvec - rx half connection ack vector | 440 | * @dccps_hc_rx_ackvec - rx half connection ack vector |
| 441 | * @dccps_xmit_timer - timer for when CCID is not ready to send | ||
| 441 | */ | 442 | */ |
| 442 | struct dccp_sock { | 443 | struct dccp_sock { |
| 443 | /* inet_connection_sock has to be the first member of dccp_sock */ | 444 | /* inet_connection_sock has to be the first member of dccp_sock */ |
| @@ -470,6 +471,7 @@ struct dccp_sock { · 26 unmodified lines | |||
| 470 | enum dccp_role dccps_role:2; | 471 | enum dccp_role dccps_role:2; |
| 471 | __u8 dccps_hc_rx_insert_options:1; | 472 | __u8 dccps_hc_rx_insert_options:1; |
| 472 | __u8 dccps_hc_tx_insert_options:1; | 473 | __u8 dccps_hc_tx_insert_options:1; |
| 474 | struct timer_list dccps_xmit_timer; | ||
| 473 | }; | 475 | }; |
| 474 | 476 | ||
| 475 | static inline struct dccp_sock *dccp_sk(const struct sock *sk) | 477 | static inline struct dccp_sock *dccp_sk(const struct sock *sk) |
| @@ -0,0 +1,65 @@ | |||
| 1 | #ifndef __LINUX_FIB_RULES_H | ||
| 2 | #define __LINUX_FIB_RULES_H | ||
| 3 | |||
| 4 | #include <linux/types.h> | ||
| 5 | #include <linux/rtnetlink.h> | ||
| 6 | |||
| 7 | /* rule is permanent, and cannot be deleted */ | ||
| 8 | #define FIB_RULE_PERMANENT 1 | ||
| 9 | |||
| 10 | struct fib_rule_hdr | ||
| 11 | { | ||
| 12 | __u8 family; | ||
| 13 | __u8 dst_len; | ||
| 14 | __u8 src_len; | ||
| 15 | __u8 tos; | ||
| 16 | |||
| 17 | __u8 table; | ||
| 18 | __u8 res1; /* reserved */ | ||
| 19 | __u8 res2; /* reserved */ | ||
| 20 | __u8 action; | ||
| 21 | |||
| 22 | __u32 flags; | ||
| 23 | }; | ||
| 24 | |||
| 25 | enum | ||
| 26 | { | ||
| 27 | FRA_UNSPEC, | ||
| 28 | FRA_DST, /* destination address */ | ||
| 29 | FRA_SRC, /* source address */ | ||
| 30 | FRA_IFNAME, /* interface name */ | ||
| 31 | FRA_UNUSED1, | ||
| 32 | FRA_UNUSED2, | ||
| 33 | FRA_PRIORITY, /* priority/preference */ | ||
| 34 | FRA_UNUSED3, | ||
| 35 | FRA_UNUSED4, | ||
| 36 | FRA_UNUSED5, | ||
| 37 | FRA_FWMARK, /* netfilter mark */ | ||
| 38 | FRA_FLOW, /* flow/class id */ | ||
| 39 | FRA_UNUSED6, | ||
| 40 | FRA_UNUSED7, | ||
| 41 | FRA_UNUSED8, | ||
| 42 | FRA_TABLE, /* Extended table id */ | ||
| 43 | FRA_FWMASK, /* mask for netfilter mark */ | ||
| 44 | __FRA_MAX | ||
| 45 | }; | ||
| 46 | |||
| 47 | #define FRA_MAX (__FRA_MAX - 1) | ||
| 48 | |||
| 49 | enum | ||
| 50 | { | ||
| 51 | FR_ACT_UNSPEC, | ||
| 52 | FR_ACT_TO_TBL, /* Pass to fixed table */ | ||
| 53 | FR_ACT_RES1, | ||
| 54 | FR_ACT_RES2, | ||
| 55 | FR_ACT_RES3, | ||
| 56 | FR_ACT_RES4, | ||
| 57 | FR_ACT_BLACKHOLE, /* Drop without notification */ | ||
| 58 | FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */ | ||
| 59 | FR_ACT_PROHIBIT, /* Drop with EACCES */ | ||
| 60 | __FR_ACT_MAX, | ||
| 61 | }; | ||
| 62 | |||
| 63 | #define FR_ACT_MAX (__FR_ACT_MAX - 1) | ||
| 64 | |||
| 65 | #endif | ||
| @@ -25,10 +25,10 @@ · 24 unmodified lines | |||
| 25 | 25 | ||
| 26 | struct sock_filter /* Filter block */ | 26 | struct sock_filter /* Filter block */ |
| 27 | { | 27 | { |
| 28 | __u16 code; /* Actual filter code */ | 28 | __u16 code; /* Actual filter code */ |
| 29 | __u8 jt; /* Jump true */ | 29 | __u8 jt; /* Jump true */ |
| 30 | __u8 jf; /* Jump false */ | 30 | __u8 jf; /* Jump false */ |
| 31 | __u32 k; /* Generic multiuse field */ | 31 | __u32 k; /* Generic multiuse field */ |
| 32 | }; | 32 | }; |
| 33 | 33 | ||
| 34 | struct sock_fprog /* Required for SO_ATTACH_FILTER. */ | 34 | struct sock_fprog /* Required for SO_ATTACH_FILTER. */ |
| @@ -41,8 +41,9 @@ struct sock_fprog /* Required for SO_ATTACH_FILTER. */ · 6 unmodified lines | |||
| 41 | struct sk_filter | 41 | struct sk_filter |
| 42 | { | 42 | { |
| 43 | atomic_t refcnt; | 43 | atomic_t refcnt; |
| 44 | unsigned int len; /* Number of filter blocks */ | 44 | unsigned int len; /* Number of filter blocks */ |
| 45 | struct sock_filter insns[0]; | 45 | struct rcu_head rcu; |
| 46 | struct sock_filter insns[0]; | ||
| 46 | }; | 47 | }; |
| 47 | 48 | ||
| 48 | static inline unsigned int sk_filter_len(struct sk_filter *fp) | 49 | static inline unsigned int sk_filter_len(struct sk_filter *fp) |
| @@ -16,6 +16,8 @@ struct genlmsghdr { · 15 unmodified lines | |||
| 16 | 16 | ||
| 17 | #define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr)) | 17 | #define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr)) |
| 18 | 18 | ||
| 19 | #define GENL_ADMIN_PERM 0x01 | ||
| 20 | |||
| 19 | /* | 21 | /* |
| 20 | * List of reserved static generic netlink identifiers: | 22 | * List of reserved static generic netlink identifiers: |
| 21 | */ | 23 | */ |
| @@ -43,9 +45,25 @@ enum { · 21 unmodified lines | |||
| 43 | CTRL_ATTR_UNSPEC, | 45 | CTRL_ATTR_UNSPEC, |
| 44 | CTRL_ATTR_FAMILY_ID, | 46 | CTRL_ATTR_FAMILY_ID, |
| 45 | CTRL_ATTR_FAMILY_NAME, | 47 | CTRL_ATTR_FAMILY_NAME, |
| 48 | CTRL_ATTR_VERSION, | ||
| 49 | CTRL_ATTR_HDRSIZE, | ||
| 50 | CTRL_ATTR_MAXATTR, | ||
| 51 | CTRL_ATTR_OPS, | ||
| 46 | __CTRL_ATTR_MAX, | 52 | __CTRL_ATTR_MAX, |
| 47 | }; | 53 | }; |
| 48 | 54 | ||
| 49 | #define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1) | 55 | #define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1) |
| 50 | 56 | ||
| 57 | enum { | ||
| 58 | CTRL_ATTR_OP_UNSPEC, | ||
| 59 | CTRL_ATTR_OP_ID, | ||
| 60 | CTRL_ATTR_OP_FLAGS, | ||
| 61 | CTRL_ATTR_OP_POLICY, | ||
| 62 | CTRL_ATTR_OP_DOIT, | ||
| 63 | CTRL_ATTR_OP_DUMPIT, | ||
| 64 | __CTRL_ATTR_OP_MAX, | ||
| 65 | }; | ||
| 66 | |||
| 67 | #define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1) | ||
| 68 | |||
| 51 | #endif /* __LINUX_GENERIC_NETLINK_H */ | 69 | #endif /* __LINUX_GENERIC_NETLINK_H */ |
| @@ -212,5 +212,134 @@ struct ifconf · 211 unmodified lines | |||
| 212 | #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ | 212 | #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ |
| 213 | #define ifc_req ifc_ifcu.ifcu_req /* array of structures */ | 213 | #define ifc_req ifc_ifcu.ifcu_req /* array of structures */ |
| 214 | 214 | ||
| 215 | /* The struct should be in sync with struct net_device_stats */ | ||
| 216 | struct rtnl_link_stats | ||
| 217 | { | ||
| 218 | __u32 rx_packets; /* total packets received */ | ||
| 219 | __u32 tx_packets; /* total packets transmitted */ | ||
| 220 | __u32 rx_bytes; /* total bytes received */ | ||
| 221 | __u32 tx_bytes; /* total bytes transmitted */ | ||
| 222 | __u32 rx_errors; /* bad packets received */ | ||
| 223 | __u32 tx_errors; /* packet transmit problems */ | ||
| 224 | __u32 rx_dropped; /* no space in linux buffers */ | ||
| 225 | __u32 tx_dropped; /* no space available in linux */ | ||
| 226 | __u32 multicast; /* multicast packets received */ | ||
| 227 | __u32 collisions; | ||
| 228 | |||
| 229 | /* detailed rx_errors: */ | ||
| 230 | __u32 rx_length_errors; | ||
| 231 | __u32 rx_over_errors; /* receiver ring buff overflow */ | ||
| 232 | __u32 rx_crc_errors; /* recved pkt with crc error */ | ||
| 233 | __u32 rx_frame_errors; /* recv'd frame alignment error */ | ||
| 234 | __u32 rx_fifo_errors; /* recv'r fifo overrun */ | ||
| 235 | __u32 rx_missed_errors; /* receiver missed packet */ | ||
| 236 | |||
| 237 | /* detailed tx_errors */ | ||
| 238 | __u32 tx_aborted_errors; | ||
| 239 | __u32 tx_carrier_errors; | ||
| 240 | __u32 tx_fifo_errors; | ||
| 241 | __u32 tx_heartbeat_errors; | ||
| 242 | __u32 tx_window_errors; | ||
| 243 | |||
| 244 | /* for cslip etc */ | ||
| 245 | __u32 rx_compressed; | ||
| 246 | __u32 tx_compressed; | ||
| 247 | }; | ||
| 248 | |||
| 249 | /* The struct should be in sync with struct ifmap */ | ||
| 250 | struct rtnl_link_ifmap | ||
| 251 | { | ||
| 252 | __u64 mem_start; | ||
| 253 | __u64 mem_end; | ||
| 254 | __u64 base_addr; | ||
| 255 | __u16 irq; | ||
| 256 | __u8 dma; | ||
| 257 | __u8 port; | ||
| 258 | }; | ||
| 259 | |||
| 260 | enum | ||
| 261 | { | ||
| 262 | IFLA_UNSPEC, | ||
| 263 | IFLA_ADDRESS, | ||
| 264 | IFLA_BROADCAST, | ||
| 265 | IFLA_IFNAME, | ||
| 266 | IFLA_MTU, | ||
| 267 | IFLA_LINK, | ||
| 268 | IFLA_QDISC, | ||
| 269 | IFLA_STATS, | ||
| 270 | IFLA_COST, | ||
| 271 | #define IFLA_COST IFLA_COST | ||
| 272 | IFLA_PRIORITY, | ||
| 273 | #define IFLA_PRIORITY IFLA_PRIORITY | ||
| 274 | IFLA_MASTER, | ||
| 275 | #define IFLA_MASTER IFLA_MASTER | ||
| 276 | IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */ | ||
| 277 | #define IFLA_WIRELESS IFLA_WIRELESS | ||
| 278 | IFLA_PROTINFO, /* Protocol specific information for a link */ | ||
| 279 | #define IFLA_PROTINFO IFLA_PROTINFO | ||
| 280 | IFLA_TXQLEN, | ||
| 281 | #define IFLA_TXQLEN IFLA_TXQLEN | ||
| 282 | IFLA_MAP, | ||
| 283 | #define IFLA_MAP IFLA_MAP | ||
| 284 | IFLA_WEIGHT, | ||
| 285 | #define IFLA_WEIGHT IFLA_WEIGHT | ||
| 286 | IFLA_OPERSTATE, | ||
| 287 | IFLA_LINKMODE, | ||
| 288 | __IFLA_MAX | ||
| 289 | }; | ||
| 290 | |||
| 291 | |||
| 292 | #define IFLA_MAX (__IFLA_MAX - 1) | ||
| 293 | |||
| 294 | /* ifi_flags. | ||
| 295 | |||
| 296 | IFF_* flags. | ||
| 297 | |||
| 298 | The only change is: | ||
| 299 | IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are | ||
| 300 | more not changeable by user. They describe link media | ||
| 301 | characteristics and set by device driver. | ||
| 302 | |||
| 303 | Comments: | ||
| 304 | - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid | ||
| 305 | - If neither of these three flags are set; | ||
| 306 | the interface is NBMA. | ||
| 307 | |||
| 308 | - IFF_MULTICAST does not mean anything special: | ||
| 309 | multicasts can be used on all not-NBMA links. | ||
| 310 | IFF_MULTICAST means that this media uses special encapsulation | ||
| 311 | for multicast frames. Apparently, all IFF_POINTOPOINT and | ||
| 312 | IFF_BROADCAST devices are able to use multicasts too. | ||
| 313 | */ | ||
| 314 | |||
| 315 | /* IFLA_LINK. | ||
| 316 | For usual devices it is equal ifi_index. | ||
| 317 | If it is a "virtual interface" (f.e. tunnel), ifi_link | ||
| 318 | can point to real physical interface (f.e. for bandwidth calculations), | ||
| 319 | or maybe 0, what means, that real media is unknown (usual | ||
| 320 | for IPIP tunnels, when route to endpoint is allowed to change) | ||
| 321 | */ | ||
| 322 | |||
| 323 | /* Subtype attributes for IFLA_PROTINFO */ | ||
| 324 | enum | ||
| 325 | { | ||
| 326 | IFLA_INET6_UNSPEC, | ||
| 327 | IFLA_INET6_FLAGS, /* link flags */ | ||
| 328 | IFLA_INET6_CONF, /* sysctl parameters */ | ||
| 329 | IFLA_INET6_STATS, /* statistics */ | ||
| 330 | IFLA_INET6_MCAST, /* MC things. What of them? */ | ||
| 331 | IFLA_INET6_CACHEINFO, /* time values and max reasm size */ | ||
| 332 | __IFLA_INET6_MAX | ||
| 333 | }; | ||
| 334 | |||
| 335 | #define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1) | ||
| 336 | |||
| 337 | struct ifla_cacheinfo | ||
| 338 | { | ||
| 339 | __u32 max_reasm_len; | ||
| 340 | __u32 tstamp; /* ipv6InterfaceTable updated timestamp */ | ||
| 341 | __u32 reachable_time; | ||
| 342 | __u32 retrans_time; | ||
| 343 | }; | ||
| 215 | 344 | ||
| 216 | #endif /* _LINUX_IF_H */ | 345 | #endif /* _LINUX_IF_H */ |
| @@ -0,0 +1,55 @@ | |||
| 1 | #ifndef __LINUX_IF_ADDR_H | ||
| 2 | #define __LINUX_IF_ADDR_H | ||
| 3 | |||
| 4 | #include <linux/netlink.h> | ||
| 5 | |||
| 6 | struct ifaddrmsg | ||
| 7 | { | ||
| 8 | __u8 ifa_family; | ||
| 9 | __u8 ifa_prefixlen; /* The prefix length */ | ||
| 10 | __u8 ifa_flags; /* Flags */ | ||
| 11 | __u8 ifa_scope; /* Address scope */ | ||
| 12 | __u32 ifa_index; /* Link index */ | ||
| 13 | }; | ||
| 14 | |||
| 15 | /* | ||
| 16 | * Important comment: | ||
| 17 | * IFA_ADDRESS is prefix address, rather than local interface address. | ||
| 18 | * It makes no difference for normally configured broadcast interfaces, | ||
| 19 | * but for point-to-point IFA_ADDRESS is DESTINATION address, | ||
| 20 | * local address is supplied in IFA_LOCAL attribute. | ||
| 21 | */ | ||
| 22 | enum | ||
| 23 | { | ||
| 24 | IFA_UNSPEC, | ||
| 25 | IFA_ADDRESS, | ||
| 26 | IFA_LOCAL, | ||
| 27 | IFA_LABEL, | ||
| 28 | IFA_BROADCAST, | ||
| 29 | IFA_ANYCAST, | ||
| 30 | IFA_CACHEINFO, | ||
| 31 | IFA_MULTICAST, | ||
| 32 | __IFA_MAX, | ||
| 33 | }; | ||
| 34 | |||
| 35 | #define IFA_MAX (__IFA_MAX - 1) | ||
| 36 | |||
| 37 | /* ifa_flags */ | ||
| 38 | #define IFA_F_SECONDARY 0x01 | ||
| 39 | #define IFA_F_TEMPORARY IFA_F_SECONDARY | ||
| 40 | |||
| 41 | #define IFA_F_NODAD 0x02 | ||
| 42 | #define IFA_F_HOMEADDRESS 0x10 | ||
| 43 | #define IFA_F_DEPRECATED 0x20 | ||
| 44 | #define IFA_F_TENTATIVE 0x40 | ||
| 45 | #define IFA_F_PERMANENT 0x80 | ||
| 46 | |||
| 47 | struct ifa_cacheinfo | ||
| 48 | { | ||
| 49 | __u32 ifa_prefered; | ||
| 50 | __u32 ifa_valid; | ||
| 51 | __u32 cstamp; /* created timestamp, hundredths of seconds */ | ||
| 52 | __u32 tstamp; /* updated timestamp, hundredths of seconds */ | ||
| 53 | }; | ||
| 54 | |||
| 55 | #endif | ||
| @@ -52,7 +52,7 @@ enum { · 51 unmodified lines | |||
| 52 | 52 | ||
| 53 | /* Internet address. */ | 53 | /* Internet address. */ |
| 54 | struct in_addr { | 54 | struct in_addr { |
| 55 | __u32 s_addr; | 55 | __be32 s_addr; |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | #define IP_TOS 1 | 58 | #define IP_TOS 1 |
| @@ -177,7 +177,7 @@ struct in_pktinfo · 118 unmodified lines | |||
| 177 | #define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */ | 177 | #define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */ |
| 178 | struct sockaddr_in { | 178 | struct sockaddr_in { |
| 179 | sa_family_t sin_family; /* Address family */ | 179 | sa_family_t sin_family; /* Address family */ |
| 180 | unsigned short int sin_port; /* Port number */ | 180 | __be16 sin_port; /* Port number */ |
| 181 | struct in_addr sin_addr; /* Internet address */ | 181 | struct in_addr sin_addr; /* Internet address */ |
| 182 | 182 | ||
| 183 | /* Pad to size of `struct sockaddr'. */ | 183 | /* Pad to size of `struct sockaddr'. */ |
| @@ -134,6 +134,7 @@ struct in6_flowlabel_req · 133 unmodified lines | |||
| 134 | #define IPPROTO_ICMPV6 58 /* ICMPv6 */ | 134 | #define IPPROTO_ICMPV6 58 /* ICMPv6 */ |
| 135 | #define IPPROTO_NONE 59 /* IPv6 no next header */ | 135 | #define IPPROTO_NONE 59 /* IPv6 no next header */ |
| 136 | #define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ | 136 | #define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ |
| 137 | #define IPPROTO_MH 135 /* IPv6 mobility header */ | ||
| 137 | 138 | ||
| 138 | /* | 139 | /* |
| 139 | * IPv6 TLV options. | 140 | * IPv6 TLV options. |
| @@ -142,6 +143,7 @@ struct in6_flowlabel_req · 2 unmodified lines | |||
| 142 | #define IPV6_TLV_PADN 1 | 143 | #define IPV6_TLV_PADN 1 |
| 143 | #define IPV6_TLV_ROUTERALERT 5 | 144 | #define IPV6_TLV_ROUTERALERT 5 |
| 144 | #define IPV6_TLV_JUMBO 194 | 145 | #define IPV6_TLV_JUMBO 194 |
| 146 | #define IPV6_TLV_HAO 201 /* home address option */ | ||
| 145 | 147 | ||
| 146 | /* | 148 | /* |
| 147 | * IPV6 socket options | 149 | * IPV6 socket options |
| @@ -46,5 +46,7 @@ · 45 unmodified lines | |||
| 46 | #include <linux/types.h> | 46 | #include <linux/types.h> |
| 47 | 47 | ||
| 48 | extern __be32 in_aton(const char *str); | 48 | extern __be32 in_aton(const char *str); |
| 49 | extern int in4_pton(const char *src, int srclen, u8 *dst, char delim, const char **end); | ||
| 50 | extern int in6_pton(const char *src, int srclen, u8 *dst, char delim, const char **end); | ||
| 49 | #endif | 51 | #endif |
| 50 | #endif /* _LINUX_INET_H */ | 52 | #endif /* _LINUX_INET_H */ |
| @@ -57,6 +57,7 @@ · 56 unmodified lines | |||
| 57 | #define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY) | 57 | #define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY) |
| 58 | #define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY) | 58 | #define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY) |
| 59 | #define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT) | 59 | #define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT) |
| 60 | #define IPOPT_CIPSO (6 |IPOPT_CONTROL|IPOPT_COPY) | ||
| 60 | #define IPOPT_RR (7 |IPOPT_CONTROL) | 61 | #define IPOPT_RR (7 |IPOPT_CONTROL) |
| 61 | #define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY) | 62 | #define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY) |
| 62 | #define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY) | 63 | #define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY) |
| @@ -29,6 +29,7 @@ struct in6_ifreq { · 28 unmodified lines | |||
| 29 | 29 | ||
| 30 | #define IPV6_SRCRT_STRICT 0x01 /* this hop must be a neighbor */ | 30 | #define IPV6_SRCRT_STRICT 0x01 /* this hop must be a neighbor */ |
| 31 | #define IPV6_SRCRT_TYPE_0 0 /* IPv6 type 0 Routing Header */ | 31 | #define IPV6_SRCRT_TYPE_0 0 /* IPv6 type 0 Routing Header */ |
| 32 | #define IPV6_SRCRT_TYPE_2 2 /* IPv6 type 2 Routing Header */ | ||
| 32 | 33 | ||
| 33 | /* | 34 | /* |
| 34 | * routing header | 35 | * routing header |
| @@ -73,6 +74,28 @@ struct rt0_hdr { · 38 unmodified lines | |||
| 73 | #define rt0_type rt_hdr.type | 74 | #define rt0_type rt_hdr.type |
| 74 | }; | 75 | }; |
| 75 | 76 | ||
| 77 | /* | ||
| 78 | * routing header type 2 | ||
| 79 | */ | ||
| 80 | |||
| 81 | struct rt2_hdr { | ||
| 82 | struct ipv6_rt_hdr rt_hdr; | ||
| 83 | __u32 reserved; | ||
| 84 | struct in6_addr addr; | ||
| 85 | |||
| 86 | #define rt2_type rt_hdr.type | ||
| 87 | }; | ||
| 88 | |||
| 89 | /* | ||
| 90 | * home address option in destination options header | ||
| 91 | */ | ||
| 92 | |||
| 93 | struct ipv6_destopt_hao { | ||
| 94 | __u8 type; | ||
| 95 | __u8 length; | ||
| 96 | struct in6_addr addr; | ||
| 97 | } __attribute__ ((__packed__)); | ||
| 98 | |||
| 76 | struct ipv6_auth_hdr { | 99 | struct ipv6_auth_hdr { |
| 77 | __u8 nexthdr; | 100 | __u8 nexthdr; |
| 78 | __u8 hdrlen; /* This one is measured in 32 bit units! */ | 101 | __u8 hdrlen; /* This one is measured in 32 bit units! */ |
| @@ -153,6 +176,7 @@ struct ipv6_devconf { · 74 unmodified lines | |||
| 153 | __s32 accept_ra_rt_info_max_plen; | 176 | __s32 accept_ra_rt_info_max_plen; |
| 154 | #endif | 177 | #endif |
| 155 | #endif | 178 | #endif |
| 179 | __s32 proxy_ndp; | ||
| 156 | void *sysctl; | 180 | void *sysctl; |
| 157 | }; | 181 | }; |
| 158 | 182 | ||
| @@ -180,6 +204,7 @@ enum { · 21 unmodified lines | |||
| 180 | DEVCONF_ACCEPT_RA_RTR_PREF, | 204 | DEVCONF_ACCEPT_RA_RTR_PREF, |
| 181 | DEVCONF_RTR_PROBE_INTERVAL, | 205 | DEVCONF_RTR_PROBE_INTERVAL, |
| 182 | DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, | 206 | DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, |
| 207 | DEVCONF_PROXY_NDP, | ||
| 183 | DEVCONF_MAX | 208 | DEVCONF_MAX |
| 184 | }; | 209 | }; |
| 185 | 210 | ||
| @@ -206,6 +231,9 @@ struct inet6_skb_parm { · 20 unmodified lines | |||
| 206 | __u16 lastopt; | 231 | __u16 lastopt; |
| 207 | __u32 nhoff; | 232 | __u32 nhoff; |
| 208 | __u16 flags; | 233 | __u16 flags; |
| 234 | #ifdef CONFIG_IPV6_MIP6 | ||
| 235 | __u16 dsthao; | ||
| 236 | #endif | ||
| 209 | 237 | ||
| 210 | #define IP6SKB_XFRM_TRANSFORMED 1 | 238 | #define IP6SKB_XFRM_TRANSFORMED 1 |
| 211 | }; | 239 | }; |
| @@ -242,6 +270,9 @@ struct ipv6_pinfo { · 30 unmodified lines | |||
| 242 | struct in6_addr rcv_saddr; | 270 | struct in6_addr rcv_saddr; |
| 243 | struct in6_addr daddr; | 271 | struct in6_addr daddr; |
| 244 | struct in6_addr *daddr_cache; | 272 | struct in6_addr *daddr_cache; |
| 273 | #ifdef CONFIG_IPV6_SUBTREES | ||
| 274 | struct in6_addr *saddr_cache; | ||
| 275 | #endif | ||
| 245 | 276 | ||
| 246 | __u32 flow_label; | 277 | __u32 flow_label; |
| 247 | __u32 frag_size; | 278 | __u32 frag_size; |
| @@ -31,7 +31,7 @@ extern const char linux_banner[]; · 30 unmodified lines | |||
| 31 | #define STACK_MAGIC 0xdeadbeef | 31 | #define STACK_MAGIC 0xdeadbeef |
| 32 | 32 | ||
| 33 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | 33 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) |
| 34 | #define ALIGN(x,a) (((x)+(a)-1)&~((a)-1)) | 34 | #define ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL)) |
| 35 | #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) | 35 | #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) |
| 36 | #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) | 36 | #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) |
| 37 | 37 | ||
| @@ -0,0 +1,159 @@ | |||
| 1 | #ifndef __LINUX_NEIGHBOUR_H | ||
| 2 | #define __LINUX_NEIGHBOUR_H | ||
| 3 | |||
| 4 | #include <linux/netlink.h> | ||
| 5 | |||
| 6 | struct ndmsg | ||
| 7 | { | ||
| 8 | __u8 ndm_family; | ||
| 9 | __u8 ndm_pad1; | ||
| 10 | __u16 ndm_pad2; | ||
| 11 | __s32 ndm_ifindex; | ||
| 12 | __u16 ndm_state; | ||
| 13 | __u8 ndm_flags; | ||
| 14 | __u8 ndm_type; | ||
| 15 | }; | ||
| 16 | |||
| 17 | enum | ||
| 18 | { | ||
| 19 | NDA_UNSPEC, | ||
| 20 | NDA_DST, | ||
| 21 | NDA_LLADDR, | ||
| 22 | NDA_CACHEINFO, | ||
| 23 | NDA_PROBES, | ||
| 24 | __NDA_MAX | ||
| 25 | }; | ||
| 26 | |||
| 27 | #define NDA_MAX (__NDA_MAX - 1) | ||
| 28 | |||
| 29 | /* | ||
| 30 | * Neighbor Cache Entry Flags | ||
| 31 | */ | ||
| 32 | |||
| 33 | #define NTF_PROXY 0x08 /* == ATF_PUBL */ | ||
| 34 | #define NTF_ROUTER 0x80 | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Neighbor Cache Entry States. | ||
| 38 | */ | ||
| 39 | |||
| 40 | #define NUD_INCOMPLETE 0x01 | ||
| 41 | #define NUD_REACHABLE 0x02 | ||
| 42 | #define NUD_STALE 0x04 | ||
| 43 | #define NUD_DELAY 0x08 | ||
| 44 | #define NUD_PROBE 0x10 | ||
| 45 | #define NUD_FAILED 0x20 | ||
| 46 | |||
| 47 | /* Dummy states */ | ||
| 48 | #define NUD_NOARP 0x40 | ||
| 49 | #define NUD_PERMANENT 0x80 | ||
| 50 | #define NUD_NONE 0x00 | ||
| 51 | |||
| 52 | /* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change | ||
| 53 | and make no address resolution or NUD. | ||
| 54 | NUD_PERMANENT is also cannot be deleted by garbage collectors. | ||
| 55 | */ | ||
| 56 | |||
| 57 | struct nda_cacheinfo | ||
| 58 | { | ||
| 59 | __u32 ndm_confirmed; | ||
| 60 | __u32 ndm_used; | ||
| 61 | __u32 ndm_updated; | ||
| 62 | __u32 ndm_refcnt; | ||
| 63 | }; | ||
| 64 | |||
| 65 | /***************************************************************** | ||
| 66 | * Neighbour tables specific messages. | ||
| 67 | * | ||
| 68 | * To retrieve the neighbour tables send RTM_GETNEIGHTBL with the | ||
| 69 | * NLM_F_DUMP flag set. Every neighbour table configuration is | ||
| 70 | * spread over multiple messages to avoid running into message | ||
| 71 | * size limits on systems with many interfaces. The first message | ||
| 72 | * in the sequence transports all not device specific data such as | ||
| 73 | * statistics, configuration, and the default parameter set. | ||
| 74 | * This message is followed by 0..n messages carrying device | ||
| 75 | * specific parameter sets. | ||
| 76 | * Although the ordering should be sufficient, NDTA_NAME can be | ||
| 77 | * used to identify sequences. The initial message can be identified | ||
| 78 | * by checking for NDTA_CONFIG. The device specific messages do | ||
| 79 | * not contain this TLV but have NDTPA_IFINDEX set to the | ||
| 80 | * corresponding interface index. | ||
| 81 | * | ||
| 82 | * To change neighbour table attributes, send RTM_SETNEIGHTBL | ||
| 83 | * with NDTA_NAME set. Changeable attribute include NDTA_THRESH[1-3], | ||
| 84 | * NDTA_GC_INTERVAL, and all TLVs in NDTA_PARMS unless marked | ||
| 85 | * otherwise. Device specific parameter sets can be changed by | ||
| 86 | * setting NDTPA_IFINDEX to the interface index of the corresponding | ||
| 87 | * device. | ||
| 88 | ****/ | ||
| 89 | |||
| 90 | struct ndt_stats | ||
| 91 | { | ||
| 92 | __u64 ndts_allocs; | ||
| 93 | __u64 ndts_destroys; | ||
| 94 | __u64 ndts_hash_grows; | ||
| 95 | __u64 ndts_res_failed; | ||
| 96 | __u64 ndts_lookups; | ||
| 97 | __u64 ndts_hits; | ||
| 98 | __u64 ndts_rcv_probes_mcast; | ||
| 99 | __u64 ndts_rcv_probes_ucast; | ||
| 100 | __u64 ndts_periodic_gc_runs; | ||
| 101 | __u64 ndts_forced_gc_runs; | ||
| 102 | }; | ||
| 103 | |||
| 104 | enum { | ||
| 105 | NDTPA_UNSPEC, | ||
| 106 | NDTPA_IFINDEX, /* u32, unchangeable */ | ||
| 107 | NDTPA_REFCNT, /* u32, read-only */ | ||
| 108 | NDTPA_REACHABLE_TIME, /* u64, read-only, msecs */ | ||
| 109 | NDTPA_BASE_REACHABLE_TIME, /* u64, msecs */ | ||
| 110 | NDTPA_RETRANS_TIME, /* u64, msecs */ | ||
| 111 | NDTPA_GC_STALETIME, /* u64, msecs */ | ||
| 112 | NDTPA_DELAY_PROBE_TIME, /* u64, msecs */ | ||
| 113 | NDTPA_QUEUE_LEN, /* u32 */ | ||
| 114 | NDTPA_APP_PROBES, /* u32 */ | ||
| 115 | NDTPA_UCAST_PROBES, /* u32 */ | ||
| 116 | NDTPA_MCAST_PROBES, /* u32 */ | ||
| 117 | NDTPA_ANYCAST_DELAY, /* u64, msecs */ | ||
| 118 | NDTPA_PROXY_DELAY, /* u64, msecs */ | ||
| 119 | NDTPA_PROXY_QLEN, /* u32 */ | ||
| 120 | NDTPA_LOCKTIME, /* u64, msecs */ | ||
| 121 | __NDTPA_MAX | ||
| 122 | }; | ||
| 123 | #define NDTPA_MAX (__NDTPA_MAX - 1) | ||
| 124 | |||
| 125 | struct ndtmsg | ||
| 126 | { | ||
| 127 | __u8 ndtm_family; | ||
| 128 | __u8 ndtm_pad1; | ||
| 129 | __u16 ndtm_pad2; | ||
| 130 | }; | ||
| 131 | |||
| 132 | struct ndt_config | ||
| 133 | { | ||
| 134 | __u16 ndtc_key_len; | ||
| 135 | __u16 ndtc_entry_size; | ||
| 136 | __u32 ndtc_entries; | ||
| 137 | __u32 ndtc_last_flush; /* delta to now in msecs */ | ||
| 138 | __u32 ndtc_last_rand; /* delta to now in msecs */ | ||
| 139 | __u32 ndtc_hash_rnd; | ||
| 140 | __u32 ndtc_hash_mask; | ||
| 141 | __u32 ndtc_hash_chain_gc; | ||
| 142 | __u32 ndtc_proxy_qlen; | ||
| 143 | }; | ||
| 144 | |||
| 145 | enum { | ||
| 146 | NDTA_UNSPEC, | ||
| 147 | NDTA_NAME, /* char *, unchangeable */ | ||
| 148 | NDTA_THRESH1, /* u32 */ | ||
| 149 | NDTA_THRESH2, /* u32 */ | ||
| 150 | NDTA_THRESH3, /* u32 */ | ||
| 151 | NDTA_CONFIG, /* struct ndt_config, read-only */ | ||
| 152 | NDTA_PARMS, /* nested TLV NDTPA_* */ | ||
| 153 | NDTA_STATS, /* struct ndt_stats, read-only */ | ||
| 154 | NDTA_GC_INTERVAL, /* u64, msecs */ | ||
| 155 | __NDTA_MAX | ||
| 156 | }; | ||
| 157 | #define NDTA_MAX (__NDTA_MAX - 1) | ||
| 158 | |||
| 159 | #endif | ||
| @@ -169,11 +169,6 @@ struct proto_ops { · 168 unmodified lines | |||
| 169 | struct net_proto_family { | 169 | struct net_proto_family { |
| 170 | int family; | 170 | int family; |
| 171 | int (*create)(struct socket *sock, int protocol); | 171 | int (*create)(struct socket *sock, int protocol); |
| 172 | /* These are counters for the number of different methods of | ||
| 173 | each we support */ | ||
| 174 | short authentication; | ||
| 175 | short encryption; | ||
| 176 | short encrypt_net; | ||
| 177 | struct module *owner; | 172 | struct module *owner; |
| 178 | }; | 173 | }; |
| 179 | 174 | ||
| @@ -181,8 +176,8 @@ struct iovec; · 1 unmodified line | |||
| 181 | struct kvec; | 176 | struct kvec; |
| 182 | 177 | ||
| 183 | extern int sock_wake_async(struct socket *sk, int how, int band); | 178 | extern int sock_wake_async(struct socket *sk, int how, int band); |
| 184 | extern int sock_register(struct net_proto_family *fam); | 179 | extern int sock_register(const struct net_proto_family *fam); |
| 185 | extern int sock_unregister(int family); | 180 | extern void sock_unregister(int family); |
| 186 | extern int sock_create(int family, int type, int proto, | 181 | extern int sock_create(int family, int type, int proto, |
| 187 | struct socket **res); | 182 | struct socket **res); |
| 188 | extern int sock_create_kern(int family, int type, int proto, | 183 | extern int sock_create_kern(int family, int type, int proto, |
| @@ -208,6 +203,25 @@ extern int kernel_recvmsg(struct socket *sock, struct msghdr *msg, · 19 unmodified lines | |||
| 208 | struct kvec *vec, size_t num, | 203 | struct kvec *vec, size_t num, |
| 209 | size_t len, int flags); | 204 | size_t len, int flags); |
| 210 | 205 | ||
| 206 | extern int kernel_bind(struct socket *sock, struct sockaddr *addr, | ||
| 207 | int addrlen); | ||
| 208 | extern int kernel_listen(struct socket *sock, int backlog); | ||
| 209 | extern int kernel_accept(struct socket *sock, struct socket **newsock, | ||
| 210 | int flags); | ||
| 211 | extern int kernel_connect(struct socket *sock, struct sockaddr *addr, | ||
| 212 | int addrlen, int flags); | ||
| 213 | extern int kernel_getsockname(struct socket *sock, struct sockaddr *addr, | ||
| 214 | int *addrlen); | ||
| 215 | extern int kernel_getpeername(struct socket *sock, struct sockaddr *addr, | ||
| 216 | int *addrlen); | ||
| 217 | extern int kernel_getsockopt(struct socket *sock, int level, int optname, | ||
| 218 | char *optval, int *optlen); | ||
| 219 | extern int kernel_setsockopt(struct socket *sock, int level, int optname, | ||
| 220 | char *optval, int optlen); | ||
| 221 | extern int kernel_sendpage(struct socket *sock, struct page *page, int offset, | ||
| 222 | size_t size, int flags); | ||
| 223 | extern int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg); | ||
| 224 | |||
| 211 | #ifndef CONFIG_SMP | 225 | #ifndef CONFIG_SMP |
| 212 | #define SOCKOPS_WRAPPED(name) name | 226 | #define SOCKOPS_WRAPPED(name) name |
| 213 | #define SOCKOPS_WRAP(name, fam) | 227 | #define SOCKOPS_WRAP(name, fam) |
| @@ -976,7 +976,7 @@ extern void dev_mcast_init(void); · 975 unmodified lines | |||
| 976 | extern int netdev_max_backlog; | 976 | extern int netdev_max_backlog; |
| 977 | extern int weight_p; | 977 | extern int weight_p; |
| 978 | extern int netdev_set_master(struct net_device *dev, struct net_device *master); | 978 | extern int netdev_set_master(struct net_device *dev, struct net_device *master); |
| 979 | extern int skb_checksum_help(struct sk_buff *skb, int inward); | 979 | extern int skb_checksum_help(struct sk_buff *skb); |
| 980 | extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features); | 980 | extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features); |
| 981 | #ifdef CONFIG_BUG | 981 | #ifdef CONFIG_BUG |
| 982 | extern void netdev_rx_csum_fault(struct net_device *dev); | 982 | extern void netdev_rx_csum_fault(struct net_device *dev); |
| @@ -1012,7 +1012,7 @@ static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) · 29 unmodified lines | |||
| 1012 | { | 1012 | { |
| 1013 | return skb_is_gso(skb) && | 1013 | return skb_is_gso(skb) && |
| 1014 | (!skb_gso_ok(skb, dev->features) || | 1014 | (!skb_gso_ok(skb, dev->features) || |
| 1015 | unlikely(skb->ip_summed != CHECKSUM_HW)); | 1015 | unlikely(skb->ip_summed != CHECKSUM_PARTIAL)); |
| 1016 | } | 1016 | } |
| 1017 | 1017 | ||
| 1018 | /* On bonding slaves other than the currently active slave, suppress | 1018 | /* On bonding slaves other than the currently active slave, suppress |
| @@ -282,6 +282,12 @@ extern void nf_invalidate_cache(int pf); · 281 unmodified lines | |||
| 282 | Returns true or false. */ | 282 | Returns true or false. */ |
| 283 | extern int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len); | 283 | extern int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len); |
| 284 | 284 | ||
| 285 | extern u_int16_t nf_csum_update(u_int32_t oldval, u_int32_t newval, | ||
| 286 | u_int32_t csum); | ||
| 287 | extern u_int16_t nf_proto_csum_update(struct sk_buff *skb, | ||
| 288 | u_int32_t oldval, u_int32_t newval, | ||
| 289 | u_int16_t csum, int pseudohdr); | ||
| 290 | |||
| 285 | struct nf_afinfo { | 291 | struct nf_afinfo { |
| 286 | unsigned short family; | 292 | unsigned short family; |
| 287 | unsigned int (*checksum)(struct sk_buff *skb, unsigned int hook, | 293 | unsigned int (*checksum)(struct sk_buff *skb, unsigned int hook, |
| @@ -125,6 +125,10 @@ enum ip_conntrack_events · 124 unmodified lines | |||
| 125 | /* Counter highest bit has been set */ | 125 | /* Counter highest bit has been set */ |
| 126 | IPCT_COUNTER_FILLING_BIT = 11, | 126 | IPCT_COUNTER_FILLING_BIT = 11, |
| 127 | IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT), | 127 | IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT), |
| 128 | |||
| 129 | /* Mark is set */ | ||
| 130 | IPCT_MARK_BIT = 12, | ||
| 131 | IPCT_MARK = (1 << IPCT_MARK_BIT), | ||
| 128 | }; | 132 | }; |
| 129 | 133 | ||
| 130 | enum ip_conntrack_expect_events { | 134 | enum ip_conntrack_expect_events { |
| @@ -49,6 +49,7 @@ struct ip_ct_tcp · 48 unmodified lines | |||
| 49 | u_int32_t last_seq; /* Last sequence number seen in dir */ | 49 | u_int32_t last_seq; /* Last sequence number seen in dir */ |
| 50 | u_int32_t last_ack; /* Last sequence number seen in opposite dir */ | 50 | u_int32_t last_ack; /* Last sequence number seen in opposite dir */ |
| 51 | u_int32_t last_end; /* Last seq + len */ | 51 | u_int32_t last_end; /* Last seq + len */ |
| 52 | u_int16_t last_win; /* Last window advertisement seen in dir */ | ||
| 52 | }; | 53 | }; |
| 53 | 54 | ||
| 54 | #endif /* __KERNEL__ */ | 55 | #endif /* __KERNEL__ */ |
| @@ -43,7 +43,7 @@ struct nfattr · 42 unmodified lines | |||
| 43 | u_int16_t nfa_len; | 43 | u_int16_t nfa_len; |
| 44 | u_int16_t nfa_type; /* we use 15 bits for the type, and the highest | 44 | u_int16_t nfa_type; /* we use 15 bits for the type, and the highest |
| 45 | * bit to indicate whether the payload is nested */ | 45 | * bit to indicate whether the payload is nested */ |
| 46 | } __attribute__ ((packed)); | 46 | }; |
| 47 | 47 | ||
| 48 | /* FIXME: Apart from NFNL_NFA_NESTED shamelessly copy and pasted from | 48 | /* FIXME: Apart from NFNL_NFA_NESTED shamelessly copy and pasted from |
| 49 | * rtnetlink.h, it's time to put this in a generic file */ | 49 | * rtnetlink.h, it's time to put this in a generic file */ |
| @@ -79,7 +79,7 @@ struct nfgenmsg { · 29 unmodified lines | |||
| 79 | u_int8_t nfgen_family; /* AF_xxx */ | 79 | u_int8_t nfgen_family; /* AF_xxx */ |
| 80 | u_int8_t version; /* nfnetlink version */ | 80 | u_int8_t version; /* nfnetlink version */ |
| 81 | u_int16_t res_id; /* resource id */ | 81 | u_int16_t res_id; /* resource id */ |
| 82 | } __attribute__ ((packed)); | 82 | }; |
| 83 | 83 | ||
| 84 | #define NFNETLINK_V0 0 | 84 | #define NFNETLINK_V0 0 |
| 85 | 85 | ||
| @@ -19,18 +19,18 @@ struct nfulnl_msg_packet_hdr { · 18 unmodified lines | |||
| 19 | u_int16_t hw_protocol; /* hw protocol (network order) */ | 19 | u_int16_t hw_protocol; /* hw protocol (network order) */ |
| 20 | u_int8_t hook; /* netfilter hook */ | 20 | u_int8_t hook; /* netfilter hook */ |
| 21 | u_int8_t _pad; | 21 | u_int8_t _pad; |
| 22 | } __attribute__ ((packed)); | 22 | }; |
| 23 | 23 | ||
| 24 | struct nfulnl_msg_packet_hw { | 24 | struct nfulnl_msg_packet_hw { |
| 25 | u_int16_t hw_addrlen; | 25 | u_int16_t hw_addrlen; |
| 26 | u_int16_t _pad; | 26 | u_int16_t _pad; |
| 27 | u_int8_t hw_addr[8]; | 27 | u_int8_t hw_addr[8]; |
| 28 | } __attribute__ ((packed)); | 28 | }; |
| 29 | 29 | ||
| 30 | struct nfulnl_msg_packet_timestamp { | 30 | struct nfulnl_msg_packet_timestamp { |
| 31 | aligned_u64 sec; | 31 | aligned_u64 sec; |
| 32 | aligned_u64 usec; | 32 | aligned_u64 usec; |
| 33 | } __attribute__ ((packed)); | 33 | }; |
| 34 | 34 | ||
| 35 | #define NFULNL_PREFIXLEN 30 /* just like old log target */ | 35 | #define NFULNL_PREFIXLEN 30 /* just like old log target */ |
| 36 | 36 | ||
| @@ -22,12 +22,12 @@ struct nfqnl_msg_packet_hw { · 21 unmodified lines | |||
| 22 | u_int16_t hw_addrlen; | 22 | u_int16_t hw_addrlen; |
| 23 | u_int16_t _pad; | 23 | u_int16_t _pad; |
| 24 | u_int8_t hw_addr[8]; | 24 | u_int8_t hw_addr[8]; |
| 25 | } __attribute__ ((packed)); | 25 | }; |
| 26 | 26 | ||
| 27 | struct nfqnl_msg_packet_timestamp { | 27 | struct nfqnl_msg_packet_timestamp { |
| 28 | aligned_u64 sec; | 28 | aligned_u64 sec; |
| 29 | aligned_u64 usec; | 29 | aligned_u64 usec; |
| 30 | } __attribute__ ((packed)); | 30 | }; |
| 31 | 31 | ||
| 32 | enum nfqnl_attr_type { | 32 | enum nfqnl_attr_type { |
| 33 | NFQA_UNSPEC, | 33 | NFQA_UNSPEC, |
| @@ -49,7 +49,7 @@ enum nfqnl_attr_type { · 15 unmodified lines | |||
| 49 | struct nfqnl_msg_verdict_hdr { | 49 | struct nfqnl_msg_verdict_hdr { |
| 50 | u_int32_t verdict; | 50 | u_int32_t verdict; |
| 51 | u_int32_t id; | 51 | u_int32_t id; |
| 52 | } __attribute__ ((packed)); | 52 | }; |
| 53 | 53 | ||
| 54 | 54 | ||
| 55 | enum nfqnl_msg_config_cmds { | 55 | enum nfqnl_msg_config_cmds { |
| @@ -64,7 +64,7 @@ struct nfqnl_msg_config_cmd { · 8 unmodified lines | |||
| 64 | u_int8_t command; /* nfqnl_msg_config_cmds */ | 64 | u_int8_t command; /* nfqnl_msg_config_cmds */ |
| 65 | u_int8_t _pad; | 65 | u_int8_t _pad; |
| 66 | u_int16_t pf; /* AF_xxx for PF_[UN]BIND */ | 66 | u_int16_t pf; /* AF_xxx for PF_[UN]BIND */ |
| 67 | } __attribute__ ((packed)); | 67 | }; |
| 68 | 68 | ||
| 69 | enum nfqnl_config_mode { | 69 | enum nfqnl_config_mode { |
| 70 | NFQNL_COPY_NONE, | 70 | NFQNL_COPY_NONE, |
| @@ -138,16 +138,6 @@ struct xt_counters_info · 137 unmodified lines | |||
| 138 | 138 | ||
| 139 | #include <linux/netdevice.h> | 139 | #include <linux/netdevice.h> |
| 140 | 140 | ||
| 141 | #define ASSERT_READ_LOCK(x) | ||
| 142 | #define ASSERT_WRITE_LOCK(x) | ||
| 143 | #include <linux/netfilter_ipv4/listhelp.h> | ||
| 144 | |||
| 145 | #ifdef CONFIG_COMPAT | ||
| 146 | #define COMPAT_TO_USER 1 | ||
| 147 | #define COMPAT_FROM_USER -1 | ||
| 148 | #define COMPAT_CALC_SIZE 0 | ||
| 149 | #endif | ||
| 150 | |||
| 151 | struct xt_match | 141 | struct xt_match |
| 152 | { | 142 | { |
| 153 | struct list_head list; | 143 | struct list_head list; |
| @@ -174,21 +164,24 @@ struct xt_match · 20 unmodified lines | |||
| 174 | const void *ip, | 164 | const void *ip, |
| 175 | const struct xt_match *match, | 165 | const struct xt_match *match, |
| 176 | void *matchinfo, | 166 | void *matchinfo, |
| 177 | unsigned int matchinfosize, | ||
| 178 | unsigned int hook_mask); | 167 | unsigned int hook_mask); |
| 179 | 168 | ||
| 180 | /* Called when entry of this type deleted. */ | 169 | /* Called when entry of this type deleted. */ |
| 181 | void (*destroy)(const struct xt_match *match, void *matchinfo, | 170 | void (*destroy)(const struct xt_match *match, void *matchinfo); |
| 182 | unsigned int matchinfosize); | ||
| 183 | 171 | ||
| 184 | /* Called when userspace align differs from kernel space one */ | 172 | /* Called when userspace align differs from kernel space one */ |
| 185 | int (*compat)(void *match, void **dstptr, int *size, int convert); | 173 | void (*compat_from_user)(void *dst, void *src); |
| 174 | int (*compat_to_user)(void __user *dst, void *src); | ||
| 186 | 175 | ||
| 187 | /* Set this to THIS_MODULE if you are a module, otherwise NULL */ | 176 | /* Set this to THIS_MODULE if you are a module, otherwise NULL */ |
| 188 | struct module *me; | 177 | struct module *me; |
| 189 | 178 | ||
| 179 | /* Free to use by each match */ | ||
| 180 | unsigned long data; | ||
| 181 | |||
| 190 | char *table; | 182 | char *table; |
| 191 | unsigned int matchsize; | 183 | unsigned int matchsize; |
| 184 | unsigned int compatsize; | ||
| 192 | unsigned int hooks; | 185 | unsigned int hooks; |
| 193 | unsigned short proto; | 186 | unsigned short proto; |
| 194 | 187 | ||
| @@ -211,8 +204,7 @@ struct xt_target · 16 unmodified lines | |||
| 211 | const struct net_device *out, | 204 | const struct net_device *out, |
| 212 | unsigned int hooknum, | 205 | unsigned int hooknum, |
| 213 | const struct xt_target *target, | 206 | const struct xt_target *target, |
| 214 | const void *targinfo, | 207 | const void *targinfo); |
| 215 | void *userdata); | ||
| 216 | 208 | ||
| 217 | /* Called when user tries to insert an entry of this type: | 209 | /* Called when user tries to insert an entry of this type: |
| 218 | hook_mask is a bitmask of hooks from which it can be | 210 | hook_mask is a bitmask of hooks from which it can be |
| @@ -222,21 +214,21 @@ struct xt_target · 3 unmodified lines | |||
| 222 | const void *entry, | 214 | const void *entry, |
| 223 | const struct xt_target *target, | 215 | const struct xt_target *target, |
| 224 | void *targinfo, | 216 | void *targinfo, |
| 225 | unsigned int targinfosize, | ||
| 226 | unsigned int hook_mask); | 217 | unsigned int hook_mask); |
| 227 | 218 | ||
| 228 | /* Called when entry of this type deleted. */ | 219 | /* Called when entry of this type deleted. */ |
| 229 | void (*destroy)(const struct xt_target *target, void *targinfo, | 220 | void (*destroy)(const struct xt_target *target, void *targinfo); |
| 230 | unsigned int targinfosize); | ||
| 231 | 221 | ||
| 232 | /* Called when userspace align differs from kernel space one */ | 222 | /* Called when userspace align differs from kernel space one */ |
| 233 | int (*compat)(void *target, void **dstptr, int *size, int convert); | 223 | void (*compat_from_user)(void *dst, void *src); |
| 224 | int (*compat_to_user)(void __user *dst, void *src); | ||
| 234 | 225 | ||
| 235 | /* Set this to THIS_MODULE if you are a module, otherwise NULL */ | 226 | /* Set this to THIS_MODULE if you are a module, otherwise NULL */ |
| 236 | struct module *me; | 227 | struct module *me; |
| 237 | 228 | ||
| 238 | char *table; | 229 | char *table; |
| 239 | unsigned int targetsize; | 230 | unsigned int targetsize; |
| 231 | unsigned int compatsize; | ||
| 240 | unsigned int hooks; | 232 | unsigned int hooks; |
| 241 | unsigned short proto; | 233 | unsigned short proto; |
| 242 | 234 | ||
| @@ -290,8 +282,13 @@ struct xt_table_info · 47 unmodified lines | |||
| 290 | 282 | ||
| 291 | extern int xt_register_target(struct xt_target *target); | 283 | extern int xt_register_target(struct xt_target *target); |
| 292 | extern void xt_unregister_target(struct xt_target *target); | 284 | extern void xt_unregister_target(struct xt_target *target); |
| 285 | extern int xt_register_targets(struct xt_target *target, unsigned int n); | ||
| 286 | extern void xt_unregister_targets(struct xt_target *target, unsigned int n); | ||
| 287 | |||
| 293 | extern int xt_register_match(struct xt_match *target); | 288 | extern int xt_register_match(struct xt_match *target); |
| 294 | extern void xt_unregister_match(struct xt_match *target); | 289 | extern void xt_unregister_match(struct xt_match *target); |
| 290 | extern int xt_register_matches(struct xt_match *match, unsigned int n); | ||
| 291 | extern void xt_unregister_matches(struct xt_match *match, unsigned int n); | ||
| 295 | 292 | ||
| 296 | extern int xt_check_match(const struct xt_match *match, unsigned short family, | 293 | extern int xt_check_match(const struct xt_match *match, unsigned short family, |
| 297 | unsigned int size, const char *table, unsigned int hook, | 294 | unsigned int size, const char *table, unsigned int hook, |
| @@ -388,9 +385,18 @@ struct compat_xt_counters_info · 90 unmodified lines | |||
| 388 | 385 | ||
| 389 | extern void xt_compat_lock(int af); | 386 | extern void xt_compat_lock(int af); |
| 390 | extern void xt_compat_unlock(int af); | 387 | extern void xt_compat_unlock(int af); |
| 391 | extern int xt_compat_match(void *match, void **dstptr, int *size, int convert); | 388 | |
| 392 | extern int xt_compat_target(void *target, void **dstptr, int *size, | 389 | extern int xt_compat_match_offset(struct xt_match *match); |
| 393 | int convert); | 390 | extern void xt_compat_match_from_user(struct xt_entry_match *m, |
| 391 | void **dstptr, int *size); | ||
| 392 | extern int xt_compat_match_to_user(struct xt_entry_match *m, | ||
| 393 | void * __user *dstptr, int *size); | ||
| 394 | |||
| 395 | extern int xt_compat_target_offset(struct xt_target *target); | ||
| 396 | extern void xt_compat_target_from_user(struct xt_entry_target *t, | ||
| 397 | void **dstptr, int *size); | ||
| 398 | extern int xt_compat_target_to_user(struct xt_entry_target *t, | ||
| 399 | void * __user *dstptr, int *size); | ||
| 394 | 400 | ||
| 395 | #endif /* CONFIG_COMPAT */ | 401 | #endif /* CONFIG_COMPAT */ |
| 396 | #endif /* __KERNEL__ */ | 402 | #endif /* __KERNEL__ */ |
| @@ -0,0 +1,20 @@ | |||
| 1 | /* x_tables module for setting the IPv4/IPv6 DSCP field | ||
| 2 | * | ||
| 3 | * (C) 2002 Harald Welte <laforge@gnumonks.org> | ||
| 4 | * based on ipt_FTOS.c (C) 2000 by Matthew G. Marsh <mgm@paktronix.com> | ||
| 5 | * This software is distributed under GNU GPL v2, 1991 | ||
| 6 | * | ||
| 7 | * See RFC2474 for a description of the DSCP field within the IP Header. | ||
| 8 | * | ||
| 9 | * xt_DSCP.h,v 1.7 2002/03/14 12:03:13 laforge Exp | ||
| 10 | */ | ||
| 11 | #ifndef _XT_DSCP_TARGET_H | ||
| 12 | #define _XT_DSCP_TARGET_H | ||
| 13 | #include <linux/netfilter/xt_dscp.h> | ||
| 14 | |||
| 15 | /* target info */ | ||
| 16 | struct xt_DSCP_info { | ||
| 17 | u_int8_t dscp; | ||
| 18 | }; | ||
| 19 | |||
| 20 | #endif /* _XT_DSCP_TARGET_H */ | ||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* x_tables module for matching the IPv4/IPv6 DSCP field | ||
| 2 | * | ||
| 3 | * (C) 2002 Harald Welte <laforge@gnumonks.org> | ||
| 4 | * This software is distributed under GNU GPL v2, 1991 | ||
| 5 | * | ||
| 6 | * See RFC2474 for a description of the DSCP field within the IP Header. | ||
| 7 | * | ||
| 8 | * xt_dscp.h,v 1.3 2002/08/05 19:00:21 laforge Exp | ||
| 9 | */ | ||
| 10 | #ifndef _XT_DSCP_H | ||
| 11 | #define _XT_DSCP_H | ||
| 12 | |||
| 13 | #define XT_DSCP_MASK 0xfc /* 11111100 */ | ||
| 14 | #define XT_DSCP_SHIFT 2 | ||
| 15 | #define XT_DSCP_MAX 0x3f /* 00111111 */ | ||
| 16 | |||
| 17 | /* match info */ | ||
| 18 | struct xt_dscp_info { | ||
| 19 | u_int8_t dscp; | ||
| 20 | u_int8_t invert; | ||
| 21 | }; | ||
| 22 | |||
| 23 | #endif /* _XT_DSCP_H */ | ||
| @@ -248,8 +248,7 @@ extern unsigned int arpt_do_table(struct sk_buff **pskb, · 247 unmodified lines | |||
| 248 | unsigned int hook, | 248 | unsigned int hook, |
| 249 | const struct net_device *in, | 249 | const struct net_device *in, |
| 250 | const struct net_device *out, | 250 | const struct net_device *out, |
| 251 | struct arpt_table *table, | 251 | struct arpt_table *table); |
| 252 | void *userdata); | ||
| 253 | 252 | ||
| 254 | #define ARPT_ALIGN(s) (((s) + (__alignof__(struct arpt_entry)-1)) & ~(__alignof__(struct arpt_entry)-1)) | 253 | #define ARPT_ALIGN(s) (((s) + (__alignof__(struct arpt_entry)-1)) & ~(__alignof__(struct arpt_entry)-1)) |
| 255 | #endif /*__KERNEL__*/ | 254 | #endif /*__KERNEL__*/ |
| @@ -5,9 +5,8 @@ · 4 unmodified lines | |||
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <linux/netfilter.h> | 7 | #include <linux/netfilter.h> |
| 8 | #if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER) | ||
| 9 | #include <linux/if_ether.h> | 8 | #include <linux/if_ether.h> |
| 10 | #endif | 9 | #include <linux/if_vlan.h> |
| 11 | 10 | ||
| 12 | /* Bridge Hooks */ | 11 | /* Bridge Hooks */ |
| 13 | /* After promisc drops, checksum checks. */ | 12 | /* After promisc drops, checksum checks. */ |
| @@ -47,40 +46,20 @@ enum nf_br_hook_priorities { · 33 unmodified lines | |||
| 47 | 46 | ||
| 48 | 47 | ||
| 49 | /* Only used in br_forward.c */ | 48 | /* Only used in br_forward.c */ |
| 50 | static inline | 49 | extern int nf_bridge_copy_header(struct sk_buff *skb); |
| 51 | int nf_bridge_maybe_copy_header(struct sk_buff *skb) | 50 | static inline int nf_bridge_maybe_copy_header(struct sk_buff *skb) |
| 52 | { | 51 | { |
| 53 | int err; | 52 | if (skb->nf_bridge) |
| 54 | 53 | return nf_bridge_copy_header(skb); | |
| 55 | if (skb->nf_bridge) { | 54 | return 0; |
| 56 | if (skb->protocol == __constant_htons(ETH_P_8021Q)) { | ||
| 57 | err = skb_cow(skb, 18); | ||
| 58 | if (err) | ||
| 59 | return err; | ||
| 60 | memcpy(skb->data - 18, skb->nf_bridge->data, 18); | ||
| 61 | skb_push(skb, 4); | ||
| 62 | } else { | ||
| 63 | err = skb_cow(skb, 16); | ||
| 64 | if (err) | ||
| 65 | return err; | ||
| 66 | memcpy(skb->data - 16, skb->nf_bridge->data, 16); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | return 0; | ||
| 70 | } | 55 | } |
| 71 | 56 | ||
| 72 | /* This is called by the IP fragmenting code and it ensures there is | 57 | /* This is called by the IP fragmenting code and it ensures there is |
| 73 | * enough room for the encapsulating header (if there is one). */ | 58 | * enough room for the encapsulating header (if there is one). */ |
| 74 | static inline | 59 | static inline int nf_bridge_pad(const struct sk_buff *skb) |
| 75 | int nf_bridge_pad(struct sk_buff *skb) | ||
| 76 | { | 60 | { |
| 77 | if (skb->protocol == __constant_htons(ETH_P_IP)) | 61 | return (skb->nf_bridge && skb->protocol == htons(ETH_P_8021Q)) |
| 78 | return 0; | 62 | ? VLAN_HLEN : 0; |
| 79 | if (skb->nf_bridge) { | ||
| 80 | if (skb->protocol == __constant_htons(ETH_P_8021Q)) | ||
| 81 | return 4; | ||
| 82 | } | ||
| 83 | return 0; | ||
| 84 | } | 63 | } |
| 85 | 64 | ||
| 86 | struct bridge_skb_cb { | 65 | struct bridge_skb_cb { |
| @@ -90,6 +69,9 @@ struct bridge_skb_cb { · 3 unmodified lines | |||
| 90 | }; | 69 | }; |
| 91 | 70 | ||
| 92 | extern int brnf_deferred_hooks; | 71 | extern int brnf_deferred_hooks; |
| 72 | #else | ||
| 73 | #define nf_bridge_maybe_copy_header(skb) (0) | ||
| 74 | #define nf_bridge_pad(skb) (0) | ||
| 93 | #endif /* CONFIG_BRIDGE_NETFILTER */ | 75 | #endif /* CONFIG_BRIDGE_NETFILTER */ |
| 94 | 76 | ||
| 95 | #endif /* __KERNEL__ */ | 77 | #endif /* __KERNEL__ */ |
| @@ -25,6 +25,8 @@ struct ip_conntrack_helper · 24 unmodified lines | |||
| 25 | struct ip_conntrack *ct, | 25 | struct ip_conntrack *ct, |
| 26 | enum ip_conntrack_info conntrackinfo); | 26 | enum ip_conntrack_info conntrackinfo); |
| 27 | 27 | ||
| 28 | void (*destroy)(struct ip_conntrack *ct); | ||
| 29 | |||
| 28 | int (*to_nfattr)(struct sk_buff *skb, const struct ip_conntrack *ct); | 30 | int (*to_nfattr)(struct sk_buff *skb, const struct ip_conntrack *ct); |
| 29 | }; | 31 | }; |
| 30 | 32 | ||
| @@ -31,8 +31,8 @@ struct ip_ct_pptp_master { · 30 unmodified lines | |||
| 31 | /* everything below is going to be per-expectation in newnat, | 31 | /* everything below is going to be per-expectation in newnat, |
| 32 | * since there could be more than one call within one session */ | 32 | * since there could be more than one call within one session */ |
| 33 | enum pptp_ctrlcall_state cstate; /* call state */ | 33 | enum pptp_ctrlcall_state cstate; /* call state */ |
| 34 | u_int16_t pac_call_id; /* call id of PAC, host byte order */ | 34 | __be16 pac_call_id; /* call id of PAC, host byte order */ |
| 35 | u_int16_t pns_call_id; /* call id of PNS, host byte order */ | 35 | __be16 pns_call_id; /* call id of PNS, host byte order */ |
| 36 | 36 | ||
| 37 | /* in pre-2.6.11 this used to be per-expect. Now it is per-conntrack | 37 | /* in pre-2.6.11 this used to be per-expect. Now it is per-conntrack |
| 38 | * and therefore imposes a fixed limit on the number of maps */ | 38 | * and therefore imposes a fixed limit on the number of maps */ |
| @@ -42,8 +42,8 @@ struct ip_ct_pptp_master { · 3 unmodified lines | |||
| 42 | /* conntrack_expect private member */ | 42 | /* conntrack_expect private member */ |
| 43 | struct ip_ct_pptp_expect { | 43 | struct ip_ct_pptp_expect { |
| 44 | enum pptp_ctrlcall_state cstate; /* call state */ | 44 | enum pptp_ctrlcall_state cstate; /* call state */ |
| 45 | u_int16_t pac_call_id; /* call id of PAC */ | 45 | __be16 pac_call_id; /* call id of PAC */ |
| 46 | u_int16_t pns_call_id; /* call id of PNS */ | 46 | __be16 pns_call_id; /* call id of PNS */ |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | 49 | ||
| @@ -107,8 +107,7 @@ struct PptpControlHeader { · 57 unmodified lines | |||
| 107 | 107 | ||
| 108 | struct PptpStartSessionRequest { | 108 | struct PptpStartSessionRequest { |
| 109 | __be16 protocolVersion; | 109 | __be16 protocolVersion; |
| 110 | __u8 reserved1; | 110 | __u16 reserved1; |
| 111 | __u8 reserved2; | ||
| 112 | __be32 framingCapability; | 111 | __be32 framingCapability; |
| 113 | __be32 bearerCapability; | 112 | __be32 bearerCapability; |
| 114 | __be16 maxChannels; | 113 | __be16 maxChannels; |
| @@ -143,6 +142,8 @@ struct PptpStartSessionReply { · 28 unmodified lines | |||
| 143 | 142 | ||
| 144 | struct PptpStopSessionRequest { | 143 | struct PptpStopSessionRequest { |
| 145 | __u8 reason; | 144 | __u8 reason; |
| 145 | __u8 reserved1; | ||
| 146 | __u16 reserved2; | ||
| 146 | }; | 147 | }; |
| 147 | 148 | ||
| 148 | /* PptpStopSessionResultCode */ | 149 | /* PptpStopSessionResultCode */ |
| @@ -152,6 +153,7 @@ struct PptpStopSessionRequest { · 3 unmodified lines | |||
| 152 | struct PptpStopSessionReply { | 153 | struct PptpStopSessionReply { |
| 153 | __u8 resultCode; | 154 | __u8 resultCode; |
| 154 | __u8 generalErrorCode; | 155 | __u8 generalErrorCode; |
| 156 | __u16 reserved1; | ||
| 155 | }; | 157 | }; |
| 156 | 158 | ||
| 157 | struct PptpEchoRequest { | 159 | struct PptpEchoRequest { |
| @@ -188,9 +190,8 @@ struct PptpOutCallRequest { · 30 unmodified lines | |||
| 188 | __be32 framingType; | 190 | __be32 framingType; |
| 189 | __be16 packetWindow; | 191 | __be16 packetWindow; |
| 190 | __be16 packetProcDelay; | 192 | __be16 packetProcDelay; |
| 191 | __u16 reserved1; | ||
| 192 | __be16 phoneNumberLength; | 193 | __be16 phoneNumberLength; |
| 193 | __u16 reserved2; | 194 | __u16 reserved1; |
| 194 | __u8 phoneNumber[64]; | 195 | __u8 phoneNumber[64]; |
| 195 | __u8 subAddress[64]; | 196 | __u8 subAddress[64]; |
| 196 | }; | 197 | }; |
| @@ -285,19 +286,19 @@ struct PptpSetLinkInfo { · 88 unmodified lines | |||
| 285 | }; | 286 | }; |
| 286 | 287 | ||
| 287 | union pptp_ctrl_union { | 288 | union pptp_ctrl_union { |
| 288 | struct PptpStartSessionRequest sreq; | 289 | struct PptpStartSessionRequest sreq; |
| 289 | struct PptpStartSessionReply srep; | 290 | struct PptpStartSessionReply srep; |
| 290 | struct PptpStopSessionRequest streq; | 291 | struct PptpStopSessionRequest streq; |
| 291 | struct PptpStopSessionReply strep; | 292 | struct PptpStopSessionReply strep; |
| 292 | struct PptpOutCallRequest ocreq; | 293 | struct PptpOutCallRequest ocreq; |
| 293 | struct PptpOutCallReply ocack; | 294 | struct PptpOutCallReply ocack; |
| 294 | struct PptpInCallRequest icreq; | 295 | struct PptpInCallRequest icreq; |
| 295 | struct PptpInCallReply icack; | 296 | struct PptpInCallReply icack; |
| 296 | struct PptpInCallConnected iccon; | 297 | struct PptpInCallConnected iccon; |
| 297 | struct PptpClearCallRequest clrreq; | 298 | struct PptpClearCallRequest clrreq; |
| 298 | struct PptpCallDisconnectNotify disc; | 299 | struct PptpCallDisconnectNotify disc; |
| 299 | struct PptpWanErrorNotify wanerr; | 300 | struct PptpWanErrorNotify wanerr; |
| 300 | struct PptpSetLinkInfo setlink; | 301 | struct PptpSetLinkInfo setlink; |
| 301 | }; | 302 | }; |
| 302 | 303 | ||
| 303 | extern int | 304 | extern int |
| @@ -314,7 +315,7 @@ extern int · 10 unmodified lines | |||
| 314 | struct PptpControlHeader *ctlh, | 315 | struct PptpControlHeader *ctlh, |
| 315 | union pptp_ctrl_union *pptpReq); | 316 | union pptp_ctrl_union *pptpReq); |
| 316 | 317 | ||
| 317 | extern int | 318 | extern void |
| 318 | (*ip_nat_pptp_hook_exp_gre)(struct ip_conntrack_expect *exp_orig, | 319 | (*ip_nat_pptp_hook_exp_gre)(struct ip_conntrack_expect *exp_orig, |
| 319 | struct ip_conntrack_expect *exp_reply); | 320 | struct ip_conntrack_expect *exp_reply); |
| 320 | 321 | ||
| @@ -49,18 +49,18 @@ struct gre_hdr { · 48 unmodified lines | |||
| 49 | #else | 49 | #else |
| 50 | #error "Adjust your <asm/byteorder.h> defines" | 50 | #error "Adjust your <asm/byteorder.h> defines" |
| 51 | #endif | 51 | #endif |
| 52 | __u16 protocol; | 52 | __be16 protocol; |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | /* modified GRE header for PPTP */ | 55 | /* modified GRE header for PPTP */ |
| 56 | struct gre_hdr_pptp { | 56 | struct gre_hdr_pptp { |
| 57 | __u8 flags; /* bitfield */ | 57 | __u8 flags; /* bitfield */ |
| 58 | __u8 version; /* should be GRE_VERSION_PPTP */ | 58 | __u8 version; /* should be GRE_VERSION_PPTP */ |
| 59 | __u16 protocol; /* should be GRE_PROTOCOL_PPTP */ | 59 | __be16 protocol; /* should be GRE_PROTOCOL_PPTP */ |
| 60 | __u16 payload_len; /* size of ppp payload, not inc. gre header */ | 60 | __be16 payload_len; /* size of ppp payload, not inc. gre header */ |
| 61 | __u16 call_id; /* peer's call_id for this session */ | 61 | __be16 call_id; /* peer's call_id for this session */ |
| 62 | __u32 seq; /* sequence number. Present if S==1 */ | 62 | __be32 seq; /* sequence number. Present if S==1 */ |
| 63 | __u32 ack; /* seq number of highest packet recieved by */ | 63 | __be32 ack; /* seq number of highest packet recieved by */ |
| 64 | /* sender in this session */ | 64 | /* sender in this session */ |
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| @@ -92,13 +92,13 @@ void ip_ct_gre_keymap_destroy(struct ip_conntrack *ct); · 25 unmodified lines | |||
| 92 | 92 | ||
| 93 | 93 | ||
| 94 | /* get pointer to gre key, if present */ | 94 | /* get pointer to gre key, if present */ |
| 95 | static inline u_int32_t *gre_key(struct gre_hdr *greh) | 95 | static inline __be32 *gre_key(struct gre_hdr *greh) |
| 96 | { | 96 | { |
| 97 | if (!greh->key) | 97 | if (!greh->key) |
| 98 | return NULL; | 98 | return NULL; |
| 99 | if (greh->csum || greh->routing) | 99 | if (greh->csum || greh->routing) |
| 100 | return (u_int32_t *) (greh+sizeof(*greh)+4); | 100 | return (__be32 *) (greh+sizeof(*greh)+4); |
| 101 | return (u_int32_t *) (greh+sizeof(*greh)); | 101 | return (__be32 *) (greh+sizeof(*greh)); |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | /* get pointer ot gre csum, if present */ | 104 | /* get pointer ot gre csum, if present */ |
| @@ -72,10 +72,6 @@ extern unsigned int ip_nat_setup_info(struct ip_conntrack *conntrack, · 71 unmodified lines | |||
| 72 | extern int ip_nat_used_tuple(const struct ip_conntrack_tuple *tuple, | 72 | extern int ip_nat_used_tuple(const struct ip_conntrack_tuple *tuple, |
| 73 | const struct ip_conntrack *ignored_conntrack); | 73 | const struct ip_conntrack *ignored_conntrack); |
| 74 | 74 | ||
| 75 | /* Calculate relative checksum. */ | ||
| 76 | extern u_int16_t ip_nat_cheat_check(u_int32_t oldvalinv, | ||
| 77 | u_int32_t newval, | ||
| 78 | u_int16_t oldcheck); | ||
| 79 | #else /* !__KERNEL__: iptables wants this to compile. */ | 75 | #else /* !__KERNEL__: iptables wants this to compile. */ |
| 80 | #define ip_nat_multi_range ip_nat_multi_range_compat | 76 | #define ip_nat_multi_range ip_nat_multi_range_compat |
| 81 | #endif /*__KERNEL__*/ | 77 | #endif /*__KERNEL__*/ |
| @@ -11,8 +11,8 @@ extern unsigned int ip_nat_packet(struct ip_conntrack *ct, · 10 unmodified lines | |||
| 11 | unsigned int hooknum, | 11 | unsigned int hooknum, |
| 12 | struct sk_buff **pskb); | 12 | struct sk_buff **pskb); |
| 13 | 13 | ||
| 14 | extern int ip_nat_icmp_reply_translation(struct sk_buff **pskb, | 14 | extern int ip_nat_icmp_reply_translation(struct ip_conntrack *ct, |
| 15 | struct ip_conntrack *ct, | 15 | enum ip_conntrack_info ctinfo, |
| 16 | enum ip_nat_manip_type manip, | 16 | unsigned int hooknum, |
| 17 | enum ip_conntrack_dir dir); | 17 | struct sk_buff **pskb); |
| 18 | #endif /* _IP_NAT_CORE_H */ | 18 | #endif /* _IP_NAT_CORE_H */ |
| @@ -4,8 +4,8 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | /* conntrack private data */ | 5 | /* conntrack private data */ |
| 6 | struct ip_nat_pptp { | 6 | struct ip_nat_pptp { |
| 7 | u_int16_t pns_call_id; /* NAT'ed PNS call id */ | 7 | __be16 pns_call_id; /* NAT'ed PNS call id */ |
| 8 | u_int16_t pac_call_id; /* NAT'ed PAC call id */ | 8 | __be16 pac_call_id; /* NAT'ed PAC call id */ |
| 9 | }; | 9 | }; |
| 10 | 10 | ||
| 11 | #endif /* _NAT_PPTP_H */ | 11 | #endif /* _NAT_PPTP_H */ |
| @@ -312,8 +312,7 @@ extern unsigned int ipt_do_table(struct sk_buff **pskb, · 311 unmodified lines | |||
| 312 | unsigned int hook, | 312 | unsigned int hook, |
| 313 | const struct net_device *in, | 313 | const struct net_device *in, |
| 314 | const struct net_device *out, | 314 | const struct net_device *out, |
| 315 | struct ipt_table *table, | 315 | struct ipt_table *table); |
| 316 | void *userdata); | ||
| 317 | 316 | ||
| 318 | #define IPT_ALIGN(s) XT_ALIGN(s) | 317 | #define IPT_ALIGN(s) XT_ALIGN(s) |
| 319 | 318 | ||
| @@ -11,10 +11,8 @@ · 10 unmodified lines | |||
| 11 | #ifndef _IPT_DSCP_TARGET_H | 11 | #ifndef _IPT_DSCP_TARGET_H |
| 12 | #define _IPT_DSCP_TARGET_H | 12 | #define _IPT_DSCP_TARGET_H |
| 13 | #include <linux/netfilter_ipv4/ipt_dscp.h> | 13 | #include <linux/netfilter_ipv4/ipt_dscp.h> |
| 14 | #include <linux/netfilter/xt_DSCP.h> | ||
| 14 | 15 | ||
| 15 | /* target info */ | 16 | #define ipt_DSCP_info xt_DSCP_info |
| 16 | struct ipt_DSCP_info { | ||
| 17 | u_int8_t dscp; | ||
| 18 | }; | ||
| 19 | 17 | ||
| 20 | #endif /* _IPT_DSCP_TARGET_H */ | 18 | #endif /* _IPT_DSCP_TARGET_H */ |
| @@ -10,14 +10,12 @@ · 9 unmodified lines | |||
| 10 | #ifndef _IPT_DSCP_H | 10 | #ifndef _IPT_DSCP_H |
| 11 | #define _IPT_DSCP_H | 11 | #define _IPT_DSCP_H |
| 12 | 12 | ||
| 13 | #define IPT_DSCP_MASK 0xfc /* 11111100 */ | 13 | #include <linux/netfilter/xt_dscp.h> |
| 14 | #define IPT_DSCP_SHIFT 2 | ||
| 15 | #define IPT_DSCP_MAX 0x3f /* 00111111 */ | ||
| 16 | 14 | ||
| 17 | /* match info */ | 15 | #define IPT_DSCP_MASK XT_DSCP_MASK |
| 18 | struct ipt_dscp_info { | 16 | #define IPT_DSCP_SHIFT XT_DSCP_SHIFT |
| 19 | u_int8_t dscp; | 17 | #define IPT_DSCP_MAX XT_DSCP_MAX |
| 20 | u_int8_t invert; | 18 | |
| 21 | }; | 19 | #define ipt_dscp_info xt_dscp_info |
| 22 | 20 | ||
| 23 | #endif /* _IPT_DSCP_H */ | 21 | #endif /* _IPT_DSCP_H */ |
| @@ -1,123 +0,0 @@ | |||
| 1 | #ifndef _LISTHELP_H | ||
| 2 | #define _LISTHELP_H | ||
| 3 | #include <linux/list.h> | ||
| 4 | |||
| 5 | /* Header to do more comprehensive job than linux/list.h; assume list | ||
| 6 | is first entry in structure. */ | ||
| 7 | |||
| 8 | /* Return pointer to first true entry, if any, or NULL. A macro | ||
| 9 | required to allow inlining of cmpfn. */ | ||
| 10 | #define LIST_FIND(head, cmpfn, type, args...) \ | ||
| 11 | ({ \ | ||
| 12 | const struct list_head *__i, *__j = NULL; \ | ||
| 13 | \ | ||
| 14 | ASSERT_READ_LOCK(head); \ | ||
| 15 | list_for_each(__i, (head)) \ | ||
| 16 | if (cmpfn((const type)__i , ## args)) { \ | ||
| 17 | __j = __i; \ | ||
| 18 | break; \ | ||
| 19 | } \ | ||
| 20 | (type)__j; \ | ||
| 21 | }) | ||
| 22 | |||
| 23 | #define LIST_FIND_W(head, cmpfn, type, args...) \ | ||
| 24 | ({ \ | ||
| 25 | const struct list_head *__i, *__j = NULL; \ | ||
| 26 | \ | ||
| 27 | ASSERT_WRITE_LOCK(head); \ | ||
| 28 | list_for_each(__i, (head)) \ | ||
| 29 | if (cmpfn((type)__i , ## args)) { \ | ||
| 30 | __j = __i; \ | ||
| 31 | break; \ | ||
| 32 | } \ | ||
| 33 | (type)__j; \ | ||
| 34 | }) | ||
| 35 | |||
| 36 | /* Just like LIST_FIND but we search backwards */ | ||
| 37 | #define LIST_FIND_B(head, cmpfn, type, args...) \ | ||
| 38 | ({ \ | ||
| 39 | const struct list_head *__i, *__j = NULL; \ | ||
| 40 | \ | ||
| 41 | ASSERT_READ_LOCK(head); \ | ||
| 42 | list_for_each_prev(__i, (head)) \ | ||
| 43 | if (cmpfn((const type)__i , ## args)) { \ | ||
| 44 | __j = __i; \ | ||
| 45 | break; \ | ||
| 46 | } \ | ||
| 47 | (type)__j; \ | ||
| 48 | }) | ||
| 49 | |||
| 50 | static inline int | ||
| 51 | __list_cmp_same(const void *p1, const void *p2) { return p1 == p2; } | ||
| 52 | |||
| 53 | /* Is this entry in the list? */ | ||
| 54 | static inline int | ||
| 55 | list_inlist(struct list_head *head, const void *entry) | ||
| 56 | { | ||
| 57 | return LIST_FIND(head, __list_cmp_same, void *, entry) != NULL; | ||
| 58 | } | ||
| 59 | |||
| 60 | /* Delete from list. */ | ||
| 61 | #ifdef CONFIG_NETFILTER_DEBUG | ||
| 62 | #define LIST_DELETE(head, oldentry) \ | ||
| 63 | do { \ | ||
| 64 | ASSERT_WRITE_LOCK(head); \ | ||
| 65 | if (!list_inlist(head, oldentry)) \ | ||
| 66 | printk("LIST_DELETE: %s:%u `%s'(%p) not in %s.\n", \ | ||
| 67 | __FILE__, __LINE__, #oldentry, oldentry, #head); \ | ||
| 68 | else list_del((struct list_head *)oldentry); \ | ||
| 69 | } while(0) | ||
| 70 | #else | ||
| 71 | #define LIST_DELETE(head, oldentry) list_del((struct list_head *)oldentry) | ||
| 72 | #endif | ||
| 73 | |||
| 74 | /* Append. */ | ||
| 75 | static inline void | ||
| 76 | list_append(struct list_head *head, void *new) | ||
| 77 | { | ||
| 78 | ASSERT_WRITE_LOCK(head); | ||
| 79 | list_add((new), (head)->prev); | ||
| 80 | } | ||
| 81 | |||
| 82 | /* Prepend. */ | ||
| 83 | static inline void | ||
| 84 | list_prepend(struct list_head *head, void *new) | ||
| 85 | { | ||
| 86 | ASSERT_WRITE_LOCK(head); | ||
| 87 | list_add(new, head); | ||
| 88 | } | ||
| 89 | |||
| 90 | /* Insert according to ordering function; insert before first true. */ | ||
| 91 | #define LIST_INSERT(head, new, cmpfn) \ | ||
| 92 | do { \ | ||
| 93 | struct list_head *__i; \ | ||
| 94 | ASSERT_WRITE_LOCK(head); \ | ||
| 95 | list_for_each(__i, (head)) \ | ||
| 96 | if ((new), (typeof (new))__i) \ | ||
| 97 | break; \ | ||
| 98 | list_add((struct list_head *)(new), __i->prev); \ | ||
| 99 | } while(0) | ||
| 100 | |||
| 101 | /* If the field after the list_head is a nul-terminated string, you | ||
| 102 | can use these functions. */ | ||
| 103 | static inline int __list_cmp_name(const void *i, const char *name) | ||
| 104 | { | ||
| 105 | return strcmp(name, i+sizeof(struct list_head)) == 0; | ||
| 106 | } | ||
| 107 | |||
| 108 | /* Returns false if same name already in list, otherwise does insert. */ | ||
| 109 | static inline int | ||
| 110 | list_named_insert(struct list_head *head, void *new) | ||
| 111 | { | ||
| 112 | if (LIST_FIND(head, __list_cmp_name, void *, | ||
| 113 | new + sizeof(struct list_head))) | ||
| 114 | return 0; | ||
| 115 | list_prepend(head, new); | ||
| 116 | return 1; | ||
| 117 | } | ||
| 118 | |||
| 119 | /* Find this named element in the list. */ | ||
| 120 | #define list_named_find(head, name) \ | ||
| 121 | LIST_FIND(head, __list_cmp_name, void *, name) | ||
| 122 | |||
| 123 | #endif /*_LISTHELP_H*/ | ||
| @@ -73,6 +73,7 @@ enum nf_ip6_hook_priorities { · 72 unmodified lines | |||
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | #ifdef CONFIG_NETFILTER | 75 | #ifdef CONFIG_NETFILTER |
| 76 | extern int ip6_route_me_harder(struct sk_buff *skb); | ||
| 76 | extern unsigned int nf_ip6_checksum(struct sk_buff *skb, unsigned int hook, | 77 | extern unsigned int nf_ip6_checksum(struct sk_buff *skb, unsigned int hook, |
| 77 | unsigned int dataoff, u_int8_t protocol); | 78 | unsigned int dataoff, u_int8_t protocol); |
| 78 | 79 | ||
| @@ -300,8 +300,7 @@ extern unsigned int ip6t_do_table(struct sk_buff **pskb, · 299 unmodified lines | |||
| 300 | unsigned int hook, | 300 | unsigned int hook, |
| 301 | const struct net_device *in, | 301 | const struct net_device *in, |
| 302 | const struct net_device *out, | 302 | const struct net_device *out, |
| 303 | struct ip6t_table *table, | 303 | struct ip6t_table *table); |
| 304 | void *userdata); | ||
| 305 | 304 | ||
| 306 | /* Check for an extension */ | 305 | /* Check for an extension */ |
| 307 | extern int ip6t_ext_hdr(u8 nexthdr); | 306 | extern int ip6t_ext_hdr(u8 nexthdr); |
| @@ -1,33 +0,0 @@ | |||
| 1 | /* Internal logging interface, which relies on the real | ||
| 2 | LOG target modules */ | ||
| 3 | #ifndef __LINUX_NETFILTER_LOGGING_H | ||
| 4 | #define __LINUX_NETFILTER_LOGGING_H | ||
| 5 | |||
| 6 | #ifdef __KERNEL__ | ||
| 7 | #include <asm/atomic.h> | ||
| 8 | |||
| 9 | struct nf_logging_t { | ||
| 10 | void (*nf_log_packet)(struct sk_buff **pskb, | ||
| 11 | unsigned int hooknum, | ||
| 12 | const struct net_device *in, | ||
| 13 | const struct net_device *out, | ||
| 14 | const char *prefix); | ||
| 15 | void (*nf_log)(char *pfh, size_t len, | ||
| 16 | const char *prefix); | ||
| 17 | }; | ||
| 18 | |||
| 19 | extern void nf_log_register(int pf, const struct nf_logging_t *logging); | ||
| 20 | extern void nf_log_unregister(int pf, const struct nf_logging_t *logging); | ||
| 21 | |||
| 22 | extern void nf_log_packet(int pf, | ||
| 23 | struct sk_buff **pskb, | ||
| 24 | unsigned int hooknum, | ||
| 25 | const struct net_device *in, | ||
| 26 | const struct net_device *out, | ||
| 27 | const char *fmt, ...); | ||
| 28 | extern void nf_log(int pf, | ||
| 29 | char *pfh, size_t len, | ||
| 30 | const char *fmt, ...); | ||
| 31 | #endif /*__KERNEL__*/ | ||
| 32 | |||
| 33 | #endif /*__LINUX_NETFILTER_LOGGING_H*/ | ||
| @@ -42,6 +42,7 @@ · 41 unmodified lines | |||
| 42 | #include <linux/in.h> | 42 | #include <linux/in.h> |
| 43 | #include <linux/mm.h> | 43 | #include <linux/mm.h> |
| 44 | #include <linux/pagemap.h> | 44 | #include <linux/pagemap.h> |
| 45 | #include <linux/rbtree.h> | ||
| 45 | #include <linux/rwsem.h> | 46 | #include <linux/rwsem.h> |
| 46 | #include <linux/wait.h> | 47 | #include <linux/wait.h> |
| 47 | 48 | ||
| @@ -69,6 +70,8 @@ · 21 unmodified lines | |||
| 69 | * NFSv3/v4 Access mode cache entry | 70 | * NFSv3/v4 Access mode cache entry |
| 70 | */ | 71 | */ |
| 71 | struct nfs_access_entry { | 72 | struct nfs_access_entry { |
| 73 | struct rb_node rb_node; | ||
| 74 | struct list_head lru; | ||
| 72 | unsigned long jiffies; | 75 | unsigned long jiffies; |
| 73 | struct rpc_cred * cred; | 76 | struct rpc_cred * cred; |
| 74 | int mask; | 77 | int mask; |
| @@ -145,7 +148,9 @@ struct nfs_inode { · 70 unmodified lines | |||
| 145 | */ | 148 | */ |
| 146 | atomic_t data_updates; | 149 | atomic_t data_updates; |
| 147 | 150 | ||
| 148 | struct nfs_access_entry cache_access; | 151 | struct rb_root access_cache; |
| 152 | struct list_head access_cache_entry_lru; | ||
| 153 | struct list_head access_cache_inode_lru; | ||
| 149 | #ifdef CONFIG_NFS_V3_ACL | 154 | #ifdef CONFIG_NFS_V3_ACL |
| 150 | struct posix_acl *acl_access; | 155 | struct posix_acl *acl_access; |
| 151 | struct posix_acl *acl_default; | 156 | struct posix_acl *acl_default; |
| @@ -199,6 +204,7 @@ struct nfs_inode { · 47 unmodified lines | |||
| 199 | #define NFS_INO_REVALIDATING (0) /* revalidating attrs */ | 204 | #define NFS_INO_REVALIDATING (0) /* revalidating attrs */ |
| 200 | #define NFS_INO_ADVISE_RDPLUS (1) /* advise readdirplus */ | 205 | #define NFS_INO_ADVISE_RDPLUS (1) /* advise readdirplus */ |
| 201 | #define NFS_INO_STALE (2) /* possible stale inode */ | 206 | #define NFS_INO_STALE (2) /* possible stale inode */ |
| 207 | #define NFS_INO_ACL_LRU_SET (3) /* Inode is on the LRU list */ | ||
| 202 | 208 | ||
| 203 | static inline struct nfs_inode *NFS_I(struct inode *inode) | 209 | static inline struct nfs_inode *NFS_I(struct inode *inode) |
| 204 | { | 210 | { |
| @@ -209,8 +215,7 @@ static inline struct nfs_inode *NFS_I(struct inode *inode) · 4 unmodified lines | |||
| 209 | #define NFS_FH(inode) (&NFS_I(inode)->fh) | 215 | #define NFS_FH(inode) (&NFS_I(inode)->fh) |
| 210 | #define NFS_SERVER(inode) (NFS_SB(inode->i_sb)) | 216 | #define NFS_SERVER(inode) (NFS_SB(inode->i_sb)) |
| 211 | #define NFS_CLIENT(inode) (NFS_SERVER(inode)->client) | 217 | #define NFS_CLIENT(inode) (NFS_SERVER(inode)->client) |
| 212 | #define NFS_PROTO(inode) (NFS_SERVER(inode)->rpc_ops) | 218 | #define NFS_PROTO(inode) (NFS_SERVER(inode)->nfs_client->rpc_ops) |
| 213 | #define NFS_ADDR(inode) (RPC_PEERADDR(NFS_CLIENT(inode))) | ||
| 214 | #define NFS_COOKIEVERF(inode) (NFS_I(inode)->cookieverf) | 219 | #define NFS_COOKIEVERF(inode) (NFS_I(inode)->cookieverf) |
| 215 | #define NFS_READTIME(inode) (NFS_I(inode)->read_cache_jiffies) | 220 | #define NFS_READTIME(inode) (NFS_I(inode)->read_cache_jiffies) |
| 216 | #define NFS_CHANGE_ATTR(inode) (NFS_I(inode)->change_attr) | 221 | #define NFS_CHANGE_ATTR(inode) (NFS_I(inode)->change_attr) |
| @@ -297,6 +302,7 @@ extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); · 80 unmodified lines | |||
| 297 | extern int nfs_permission(struct inode *, int, struct nameidata *); | 302 | extern int nfs_permission(struct inode *, int, struct nameidata *); |
| 298 | extern int nfs_access_get_cached(struct inode *, struct rpc_cred *, struct nfs_access_entry *); | 303 | extern int nfs_access_get_cached(struct inode *, struct rpc_cred *, struct nfs_access_entry *); |
| 299 | extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *); | 304 | extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *); |
| 305 | extern void nfs_access_zap_cache(struct inode *inode); | ||
| 300 | extern int nfs_open(struct inode *, struct file *); | 306 | extern int nfs_open(struct inode *, struct file *); |
| 301 | extern int nfs_release(struct inode *, struct file *); | 307 | extern int nfs_release(struct inode *, struct file *); |
| 302 | extern int nfs_attribute_timeout(struct inode *inode); | 308 | extern int nfs_attribute_timeout(struct inode *inode); |
| @@ -579,6 +585,7 @@ extern void * nfs_root_data(void); · 276 unmodified lines | |||
| 579 | #define NFSDBG_FILE 0x0040 | 585 | #define NFSDBG_FILE 0x0040 |
| 580 | #define NFSDBG_ROOT 0x0080 | 586 | #define NFSDBG_ROOT 0x0080 |
| 581 | #define NFSDBG_CALLBACK 0x0100 | 587 | #define NFSDBG_CALLBACK 0x0100 |
| 588 | #define NFSDBG_CLIENT 0x0200 | ||
| 582 | #define NFSDBG_ALL 0xFFFF | 589 | #define NFSDBG_ALL 0xFFFF |
| 583 | 590 | ||
| 584 | #ifdef __KERNEL__ | 591 | #ifdef __KERNEL__ |
| @@ -6,14 +6,80 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | struct nfs_iostats; | 7 | struct nfs_iostats; |
| 8 | 8 | ||
| 9 | /* | ||
| 10 | * The nfs_client identifies our client state to the server. | ||
| 11 | */ | ||
| 12 | struct nfs_client { | ||
| 13 | atomic_t cl_count; | ||
| 14 | int cl_cons_state; /* current construction state (-ve: init error) */ | ||
| 15 | #define NFS_CS_READY 0 /* ready to be used */ | ||
| 16 | #define NFS_CS_INITING 1 /* busy initialising */ | ||
| 17 | int cl_nfsversion; /* NFS protocol version */ | ||
| 18 | unsigned long cl_res_state; /* NFS resources state */ | ||
| 19 | #define NFS_CS_RPCIOD 0 /* - rpciod started */ | ||
| 20 | #define NFS_CS_CALLBACK 1 /* - callback started */ | ||
| 21 | #define NFS_CS_IDMAP 2 /* - idmap started */ | ||
| 22 | #define NFS_CS_RENEWD 3 /* - renewd started */ | ||
| 23 | struct sockaddr_in cl_addr; /* server identifier */ | ||
| 24 | char * cl_hostname; /* hostname of server */ | ||
| 25 | struct list_head cl_share_link; /* link in global client list */ | ||
| 26 | struct list_head cl_superblocks; /* List of nfs_server structs */ | ||
| 27 | |||
| 28 | struct rpc_clnt * cl_rpcclient; | ||
| 29 | const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */ | ||
| 30 | unsigned long retrans_timeo; /* retransmit timeout */ | ||
| 31 | unsigned int retrans_count; /* number of retransmit tries */ | ||
| 32 | |||
| 33 | #ifdef CONFIG_NFS_V4 | ||
| 34 | u64 cl_clientid; /* constant */ | ||
| 35 | nfs4_verifier cl_confirm; | ||
| 36 | unsigned long cl_state; | ||
| 37 | |||
| 38 | u32 cl_lockowner_id; | ||
| 39 | |||
| 40 | /* | ||
| 41 | * The following rwsem ensures exclusive access to the server | ||
| 42 | * while we recover the state following a lease expiration. | ||
| 43 | */ | ||
| 44 | struct rw_semaphore cl_sem; | ||
| 45 | |||
| 46 | struct list_head cl_delegations; | ||
| 47 | struct list_head cl_state_owners; | ||
| 48 | struct list_head cl_unused; | ||
| 49 | int cl_nunused; | ||
| 50 | spinlock_t cl_lock; | ||
| 51 | |||
| 52 | unsigned long cl_lease_time; | ||
| 53 | unsigned long cl_last_renewal; | ||
| 54 | struct work_struct cl_renewd; | ||
| 55 | |||
| 56 | struct rpc_wait_queue cl_rpcwaitq; | ||
| 57 | |||
| 58 | /* used for the setclientid verifier */ | ||
| 59 | struct timespec cl_boot_time; | ||
| 60 | |||
| 61 | /* idmapper */ | ||
| 62 | struct idmap * cl_idmap; | ||
| 63 | |||
| 64 | /* Our own IP address, as a null-terminated string. | ||
| 65 | * This is used to generate the clientid, and the callback address. | ||
| 66 | */ | ||
| 67 | char cl_ipaddr[16]; | ||
| 68 | unsigned char cl_id_uniquifier; | ||
| 69 | #endif | ||
| 70 | }; | ||
| 71 | |||
| 9 | /* | 72 | /* |
| 10 | * NFS client parameters stored in the superblock. | 73 | * NFS client parameters stored in the superblock. |
| 11 | */ | 74 | */ |
| 12 | struct nfs_server { | 75 | struct nfs_server { |
| 76 | struct nfs_client * nfs_client; /* shared client and NFS4 state */ | ||
| 77 | struct list_head client_link; /* List of other nfs_server structs | ||
| 78 | * that share the same client | ||
| 79 | */ | ||
| 80 | struct list_head master_link; /* link in master servers list */ | ||
| 13 | struct rpc_clnt * client; /* RPC client handle */ | 81 | struct rpc_clnt * client; /* RPC client handle */ |
| 14 | struct rpc_clnt * client_sys; /* 2nd handle for FSINFO */ | ||
| 15 | struct rpc_clnt * client_acl; /* ACL RPC client handle */ | 82 | struct rpc_clnt * client_acl; /* ACL RPC client handle */ |
| 16 | struct nfs_rpc_ops * rpc_ops; /* NFS protocol vector */ | ||
| 17 | struct nfs_iostats * io_stats; /* I/O statistics */ | 83 | struct nfs_iostats * io_stats; /* I/O statistics */ |
| 18 | struct backing_dev_info backing_dev_info; | 84 | struct backing_dev_info backing_dev_info; |
| 19 | int flags; /* various flags */ | 85 | int flags; /* various flags */ |
| @@ -29,24 +95,14 @@ struct nfs_server { · 9 unmodified lines | |||
| 29 | unsigned int acregmax; | 95 | unsigned int acregmax; |
| 30 | unsigned int acdirmin; | 96 | unsigned int acdirmin; |
| 31 | unsigned int acdirmax; | 97 | unsigned int acdirmax; |
| 32 | unsigned long retrans_timeo; /* retransmit timeout */ | ||
| 33 | unsigned int retrans_count; /* number of retransmit tries */ | ||
| 34 | unsigned int namelen; | 98 | unsigned int namelen; |
| 35 | char * hostname; /* remote hostname */ | 99 | |
| 36 | struct nfs_fh fh; | ||
| 37 | struct sockaddr_in addr; | ||
| 38 | struct nfs_fsid fsid; | 100 | struct nfs_fsid fsid; |
| 101 | __u64 maxfilesize; /* maximum file size */ | ||
| 39 | unsigned long mount_time; /* when this fs was mounted */ | 102 | unsigned long mount_time; /* when this fs was mounted */ |
| 103 | dev_t s_dev; /* superblock dev numbers */ | ||
| 104 | |||
| 40 | #ifdef CONFIG_NFS_V4 | 105 | #ifdef CONFIG_NFS_V4 |
| 41 | /* Our own IP address, as a null-terminated string. | ||
| 42 | * This is used to generate the clientid, and the callback address. | ||
| 43 | */ | ||
| 44 | char ip_addr[16]; | ||
| 45 | char * mnt_path; | ||
| 46 | struct nfs4_client * nfs4_state; /* all NFSv4 state starts here */ | ||
| 47 | struct list_head nfs4_siblings; /* List of other nfs_server structs | ||
| 48 | * that share the same clientid | ||
| 49 | */ | ||
| 50 | u32 attr_bitmask[2];/* V4 bitmask representing the set | 106 | u32 attr_bitmask[2];/* V4 bitmask representing the set |
| 51 | of attributes supported on this | 107 | of attributes supported on this |
| 52 | filesystem */ | 108 | filesystem */ |
| @@ -54,6 +110,7 @@ struct nfs_server { · 1 unmodified line | |||
| 54 | that are supported on this | 110 | that are supported on this |
| 55 | filesystem */ | 111 | filesystem */ |
| 56 | #endif | 112 | #endif |
| 113 | void (*destroy)(struct nfs_server *); | ||
| 57 | }; | 114 | }; |
| 58 | 115 | ||
| 59 | /* Server capabilities */ | 116 | /* Server capabilities */ |
| @@ -62,15 +62,15 @@ struct idmap_msg { · 61 unmodified lines | |||
| 62 | #ifdef __KERNEL__ | 62 | #ifdef __KERNEL__ |
| 63 | 63 | ||
| 64 | /* Forward declaration to make this header independent of others */ | 64 | /* Forward declaration to make this header independent of others */ |
| 65 | struct nfs4_client; | 65 | struct nfs_client; |
| 66 | 66 | ||
| 67 | void nfs_idmap_new(struct nfs4_client *); | 67 | int nfs_idmap_new(struct nfs_client *); |
| 68 | void nfs_idmap_delete(struct nfs4_client *); | 68 | void nfs_idmap_delete(struct nfs_client *); |
| 69 | 69 | ||
| 70 | int nfs_map_name_to_uid(struct nfs4_client *, const char *, size_t, __u32 *); | 70 | int nfs_map_name_to_uid(struct nfs_client *, const char *, size_t, __u32 *); |
| 71 | int nfs_map_group_to_gid(struct nfs4_client *, const char *, size_t, __u32 *); | 71 | int nfs_map_group_to_gid(struct nfs_client *, const char *, size_t, __u32 *); |
| 72 | int nfs_map_uid_to_name(struct nfs4_client *, __u32, char *); | 72 | int nfs_map_uid_to_name(struct nfs_client *, __u32, char *); |
| 73 | int nfs_map_gid_to_group(struct nfs4_client *, __u32, char *); | 73 | int nfs_map_gid_to_group(struct nfs_client *, __u32, char *); |
| 74 | 74 | ||
| 75 | extern unsigned int nfs_idmap_cache_timeout; | 75 | extern unsigned int nfs_idmap_cache_timeout; |
| 76 | #endif /* __KERNEL__ */ | 76 | #endif /* __KERNEL__ */ |
| @@ -1,7 +1,6 @@ | |||
| 1 | #ifndef _LINUX_NFS_XDR_H | 1 | #ifndef _LINUX_NFS_XDR_H |
| 2 | #define _LINUX_NFS_XDR_H | 2 | #define _LINUX_NFS_XDR_H |
| 3 | 3 | ||
| 4 | #include <linux/sunrpc/xprt.h> | ||
| 5 | #include <linux/nfsacl.h> | 4 | #include <linux/nfsacl.h> |
| 6 | 5 | ||
| 7 | /* | 6 | /* |
| @@ -359,8 +358,8 @@ struct nfs_symlinkargs { · 351 unmodified lines | |||
| 359 | struct nfs_fh * fromfh; | 358 | struct nfs_fh * fromfh; |
| 360 | const char * fromname; | 359 | const char * fromname; |
| 361 | unsigned int fromlen; | 360 | unsigned int fromlen; |
| 362 | const char * topath; | 361 | struct page ** pages; |
| 363 | unsigned int tolen; | 362 | unsigned int pathlen; |
| 364 | struct iattr * sattr; | 363 | struct iattr * sattr; |
| 365 | }; | 364 | }; |
| 366 | 365 | ||
| @@ -435,8 +434,8 @@ struct nfs3_symlinkargs { · 68 unmodified lines | |||
| 435 | struct nfs_fh * fromfh; | 434 | struct nfs_fh * fromfh; |
| 436 | const char * fromname; | 435 | const char * fromname; |
| 437 | unsigned int fromlen; | 436 | unsigned int fromlen; |
| 438 | const char * topath; | 437 | struct page ** pages; |
| 439 | unsigned int tolen; | 438 | unsigned int pathlen; |
| 440 | struct iattr * sattr; | 439 | struct iattr * sattr; |
| 441 | }; | 440 | }; |
| 442 | 441 | ||
| @@ -534,7 +533,10 @@ struct nfs4_accessres { · 91 unmodified lines | |||
| 534 | struct nfs4_create_arg { | 533 | struct nfs4_create_arg { |
| 535 | u32 ftype; | 534 | u32 ftype; |
| 536 | union { | 535 | union { |
| 537 | struct qstr * symlink; /* NF4LNK */ | 536 | struct { |
| 537 | struct page ** pages; | ||
| 538 | unsigned int len; | ||
| 539 | } symlink; /* NF4LNK */ | ||
| 538 | struct { | 540 | struct { |
| 539 | u32 specdata1; | 541 | u32 specdata1; |
| 540 | u32 specdata2; | 542 | u32 specdata2; |
| @@ -770,6 +772,9 @@ struct nfs_rpc_ops { · 229 unmodified lines | |||
| 770 | 772 | ||
| 771 | int (*getroot) (struct nfs_server *, struct nfs_fh *, | 773 | int (*getroot) (struct nfs_server *, struct nfs_fh *, |
| 772 | struct nfs_fsinfo *); | 774 | struct nfs_fsinfo *); |
| 775 | int (*lookupfh)(struct nfs_server *, struct nfs_fh *, | ||
| 776 | struct qstr *, struct nfs_fh *, | ||
| 777 | struct nfs_fattr *); | ||
| 773 | int (*getattr) (struct nfs_server *, struct nfs_fh *, | 778 | int (*getattr) (struct nfs_server *, struct nfs_fh *, |
| 774 | struct nfs_fattr *); | 779 | struct nfs_fattr *); |
| 775 | int (*setattr) (struct dentry *, struct nfs_fattr *, | 780 | int (*setattr) (struct dentry *, struct nfs_fattr *, |
| @@ -791,9 +796,8 @@ struct nfs_rpc_ops { · 15 unmodified lines | |||
| 791 | int (*rename) (struct inode *, struct qstr *, | 796 | int (*rename) (struct inode *, struct qstr *, |
| 792 | struct inode *, struct qstr *); | 797 | struct inode *, struct qstr *); |
| 793 | int (*link) (struct inode *, struct inode *, struct qstr *); | 798 | int (*link) (struct inode *, struct inode *, struct qstr *); |
| 794 | int (*symlink) (struct inode *, struct qstr *, struct qstr *, | 799 | int (*symlink) (struct inode *, struct dentry *, struct page *, |
| 795 | struct iattr *, struct nfs_fh *, | 800 | unsigned int, struct iattr *); |
| 796 | struct nfs_fattr *); | ||
| 797 | int (*mkdir) (struct inode *, struct dentry *, struct iattr *); | 801 | int (*mkdir) (struct inode *, struct dentry *, struct iattr *); |
| 798 | int (*rmdir) (struct inode *, struct qstr *); | 802 | int (*rmdir) (struct inode *, struct qstr *); |
| 799 | int (*readdir) (struct dentry *, struct rpc_cred *, | 803 | int (*readdir) (struct dentry *, struct rpc_cred *, |
| @@ -806,6 +810,7 @@ struct nfs_rpc_ops { · 6 unmodified lines | |||
| 806 | struct nfs_fsinfo *); | 810 | struct nfs_fsinfo *); |
| 807 | int (*pathconf) (struct nfs_server *, struct nfs_fh *, | 811 | int (*pathconf) (struct nfs_server *, struct nfs_fh *, |
| 808 | struct nfs_pathconf *); | 812 | struct nfs_pathconf *); |
| 813 | int (*set_capabilities)(struct nfs_server *, struct nfs_fh *); | ||
| 809 | u32 * (*decode_dirent)(u32 *, struct nfs_entry *, int plus); | 814 | u32 * (*decode_dirent)(u32 *, struct nfs_entry *, int plus); |
| 810 | void (*read_setup) (struct nfs_read_data *); | 815 | void (*read_setup) (struct nfs_read_data *); |
| 811 | int (*read_done) (struct rpc_task *, struct nfs_read_data *); | 816 | int (*read_done) (struct rpc_task *, struct nfs_read_data *); |
| @@ -829,9 +834,9 @@ struct nfs_rpc_ops { · 17 unmodified lines | |||
| 829 | /* | 834 | /* |
| 830 | * Function vectors etc. for the NFS client | 835 | * Function vectors etc. for the NFS client |
| 831 | */ | 836 | */ |
| 832 | extern struct nfs_rpc_ops nfs_v2_clientops; | 837 | extern const struct nfs_rpc_ops nfs_v2_clientops; |
| 833 | extern struct nfs_rpc_ops nfs_v3_clientops; | 838 | extern const struct nfs_rpc_ops nfs_v3_clientops; |
| 834 | extern struct nfs_rpc_ops nfs_v4_clientops; | 839 | extern const struct nfs_rpc_ops nfs_v4_clientops; |
| 835 | extern struct rpc_version nfs_version2; | 840 | extern struct rpc_version nfs_version2; |
| 836 | extern struct rpc_version nfs_version3; | 841 | extern struct rpc_version nfs_version3; |
| 837 | extern struct rpc_version nfs_version4; | 842 | extern struct rpc_version nfs_version4; |
| @@ -305,6 +305,7 @@ enum · 304 unmodified lines | |||
| 305 | TCA_FW_POLICE, | 305 | TCA_FW_POLICE, |
| 306 | TCA_FW_INDEV, /* used by CONFIG_NET_CLS_IND */ | 306 | TCA_FW_INDEV, /* used by CONFIG_NET_CLS_IND */ |
| 307 | TCA_FW_ACT, /* used by CONFIG_NET_CLS_ACT */ | 307 | TCA_FW_ACT, /* used by CONFIG_NET_CLS_ACT */ |
| 308 | TCA_FW_MASK, | ||
| 308 | __TCA_FW_MAX | 309 | __TCA_FW_MAX |
| 309 | }; | 310 | }; |
| 310 | 311 | ||
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | #define __LINUX_RTNETLINK_H | 2 | #define __LINUX_RTNETLINK_H |
| 3 | 3 | ||
| 4 | #include <linux/netlink.h> | 4 | #include <linux/netlink.h> |
| 5 | #include <linux/if.h> | ||
| 5 | 6 | ||
| 6 | /**** | 7 | /**** |
| 7 | * Routing/neighbour discovery messages. | 8 | * Routing/neighbour discovery messages. |
| @@ -238,10 +239,8 @@ enum rt_class_t · 230 unmodified lines | |||
| 238 | RT_TABLE_DEFAULT=253, | 239 | RT_TABLE_DEFAULT=253, |
| 239 | RT_TABLE_MAIN=254, | 240 | RT_TABLE_MAIN=254, |
| 240 | RT_TABLE_LOCAL=255, | 241 | RT_TABLE_LOCAL=255, |
| 241 | __RT_TABLE_MAX | 242 | RT_TABLE_MAX=0xFFFFFFFF |
| 242 | }; | 243 | }; |
| 243 | #define RT_TABLE_MAX (__RT_TABLE_MAX - 1) | ||
| 244 | |||
| 245 | 244 | ||
| 246 | 245 | ||
| 247 | /* Routing message attributes */ | 246 | /* Routing message attributes */ |
| @@ -263,6 +262,7 @@ enum rtattr_type_t · 15 unmodified lines | |||
| 263 | RTA_CACHEINFO, | 262 | RTA_CACHEINFO, |
| 264 | RTA_SESSION, | 263 | RTA_SESSION, |
| 265 | RTA_MP_ALGO, | 264 | RTA_MP_ALGO, |
| 265 | RTA_TABLE, | ||
| 266 | __RTA_MAX | 266 | __RTA_MAX |
| 267 | }; | 267 | }; |
| 268 | 268 | ||
| @@ -383,226 +383,6 @@ struct rta_session · 114 unmodified lines | |||
| 383 | } u; | 383 | } u; |
| 384 | }; | 384 | }; |
| 385 | 385 | ||
| 386 | |||
| 387 | /********************************************************* | ||
| 388 | * Interface address. | ||
| 389 | ****/ | ||
| 390 | |||
| 391 | struct ifaddrmsg | ||
| 392 | { | ||
| 393 | unsigned char ifa_family; | ||
| 394 | unsigned char ifa_prefixlen; /* The prefix length */ | ||
| 395 | unsigned char ifa_flags; /* Flags */ | ||
| 396 | unsigned char ifa_scope; /* See above */ | ||
| 397 | int ifa_index; /* Link index */ | ||
| 398 | }; | ||
| 399 | |||
| 400 | enum | ||
| 401 | { | ||
| 402 | IFA_UNSPEC, | ||
| 403 | IFA_ADDRESS, | ||
| 404 | IFA_LOCAL, | ||
| 405 | IFA_LABEL, | ||
| 406 | IFA_BROADCAST, | ||
| 407 | IFA_ANYCAST, | ||
| 408 | IFA_CACHEINFO, | ||
| 409 | IFA_MULTICAST, | ||
| 410 | __IFA_MAX | ||
| 411 | }; | ||
| 412 | |||
| 413 | #define IFA_MAX (__IFA_MAX - 1) | ||
| 414 | |||
| 415 | /* ifa_flags */ | ||
| 416 | |||
| 417 | #define IFA_F_SECONDARY 0x01 | ||
| 418 | #define IFA_F_TEMPORARY IFA_F_SECONDARY | ||
| 419 | |||
| 420 | #define IFA_F_DEPRECATED 0x20 | ||
| 421 | #define IFA_F_TENTATIVE 0x40 | ||
| 422 | #define IFA_F_PERMANENT 0x80 | ||
| 423 | |||
| 424 | struct ifa_cacheinfo | ||
| 425 | { | ||
| 426 | __u32 ifa_prefered; | ||
| 427 | __u32 ifa_valid; | ||
| 428 | __u32 cstamp; /* created timestamp, hundredths of seconds */ | ||
| 429 | __u32 tstamp; /* updated timestamp, hundredths of seconds */ | ||
| 430 | }; | ||
| 431 | |||
| 432 | |||
| 433 | #define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)))) | ||
| 434 | #define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg)) | ||
| 435 | |||
| 436 | /* | ||
| 437 | Important comment: | ||
| 438 | IFA_ADDRESS is prefix address, rather than local interface address. | ||
| 439 | It makes no difference for normally configured broadcast interfaces, | ||
| 440 | but for point-to-point IFA_ADDRESS is DESTINATION address, | ||
| 441 | local address is supplied in IFA_LOCAL attribute. | ||
| 442 | */ | ||
| 443 | |||
| 444 | /************************************************************** | ||
| 445 | * Neighbour discovery. | ||
| 446 | ****/ | ||
| 447 | |||
| 448 | struct ndmsg | ||
| 449 | { | ||
| 450 | unsigned char ndm_family; | ||
| 451 | unsigned char ndm_pad1; | ||
| 452 | unsigned short ndm_pad2; | ||
| 453 | int ndm_ifindex; /* Link index */ | ||
| 454 | __u16 ndm_state; | ||
| 455 | __u8 ndm_flags; | ||
| 456 | __u8 ndm_type; | ||
| 457 | }; | ||
| 458 | |||
| 459 | enum | ||
| 460 | { | ||
| 461 | NDA_UNSPEC, | ||
| 462 | NDA_DST, | ||
| 463 | NDA_LLADDR, | ||
| 464 | NDA_CACHEINFO, | ||
| 465 | NDA_PROBES, | ||
| 466 | __NDA_MAX | ||
| 467 | }; | ||
| 468 | |||
| 469 | #define NDA_MAX (__NDA_MAX - 1) | ||
| 470 | |||
| 471 | #define NDA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) | ||
| 472 | #define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg)) | ||
| 473 | |||
| 474 | /* | ||
| 475 | * Neighbor Cache Entry Flags | ||
| 476 | */ | ||
| 477 | |||
| 478 | #define NTF_PROXY 0x08 /* == ATF_PUBL */ | ||
| 479 | #define NTF_ROUTER 0x80 | ||
| 480 | |||
| 481 | /* | ||
| 482 | * Neighbor Cache Entry States. | ||
| 483 | */ | ||
| 484 | |||
| 485 | #define NUD_INCOMPLETE 0x01 | ||
| 486 | #define NUD_REACHABLE 0x02 | ||
| 487 | #define NUD_STALE 0x04 | ||
| 488 | #define NUD_DELAY 0x08 | ||
| 489 | #define NUD_PROBE 0x10 | ||
| 490 | #define NUD_FAILED 0x20 | ||
| 491 | |||
| 492 | /* Dummy states */ | ||
| 493 | #define NUD_NOARP 0x40 | ||
| 494 | #define NUD_PERMANENT 0x80 | ||
| 495 | #define NUD_NONE 0x00 | ||
| 496 | |||
| 497 | |||
| 498 | struct nda_cacheinfo | ||
| 499 | { | ||
| 500 | __u32 ndm_confirmed; | ||
| 501 | __u32 ndm_used; | ||
| 502 | __u32 ndm_updated; | ||
| 503 | __u32 ndm_refcnt; | ||
| 504 | }; | ||
| 505 | |||
| 506 | |||
| 507 | /***************************************************************** | ||
| 508 | * Neighbour tables specific messages. | ||
| 509 | * | ||
| 510 | * To retrieve the neighbour tables send RTM_GETNEIGHTBL with the | ||
| 511 | * NLM_F_DUMP flag set. Every neighbour table configuration is | ||
| 512 | * spread over multiple messages to avoid running into message | ||
| 513 | * size limits on systems with many interfaces. The first message | ||
| 514 | * in the sequence transports all not device specific data such as | ||
| 515 | * statistics, configuration, and the default parameter set. | ||
| 516 | * This message is followed by 0..n messages carrying device | ||
| 517 | * specific parameter sets. | ||
| 518 | * Although the ordering should be sufficient, NDTA_NAME can be | ||
| 519 | * used to identify sequences. The initial message can be identified | ||
| 520 | * by checking for NDTA_CONFIG. The device specific messages do | ||
| 521 | * not contain this TLV but have NDTPA_IFINDEX set to the | ||
| 522 | * corresponding interface index. | ||
| 523 | * | ||
| 524 | * To change neighbour table attributes, send RTM_SETNEIGHTBL | ||
| 525 | * with NDTA_NAME set. Changeable attribute include NDTA_THRESH[1-3], | ||
| 526 | * NDTA_GC_INTERVAL, and all TLVs in NDTA_PARMS unless marked | ||
| 527 | * otherwise. Device specific parameter sets can be changed by | ||
| 528 | * setting NDTPA_IFINDEX to the interface index of the corresponding | ||
| 529 | * device. | ||
| 530 | ****/ | ||
| 531 | |||
| 532 | struct ndt_stats | ||
| 533 | { | ||
| 534 | __u64 ndts_allocs; | ||
| 535 | __u64 ndts_destroys; | ||
| 536 | __u64 ndts_hash_grows; | ||
| 537 | __u64 ndts_res_failed; | ||
| 538 | __u64 ndts_lookups; | ||
| 539 | __u64 ndts_hits; | ||
| 540 | __u64 ndts_rcv_probes_mcast; | ||
| 541 | __u64 ndts_rcv_probes_ucast; | ||
| 542 | __u64 ndts_periodic_gc_runs; | ||
| 543 | __u64 ndts_forced_gc_runs; | ||
| 544 | }; | ||
| 545 | |||
| 546 | enum { | ||
| 547 | NDTPA_UNSPEC, | ||
| 548 | NDTPA_IFINDEX, /* u32, unchangeable */ | ||
| 549 | NDTPA_REFCNT, /* u32, read-only */ | ||
| 550 | NDTPA_REACHABLE_TIME, /* u64, read-only, msecs */ | ||
| 551 | NDTPA_BASE_REACHABLE_TIME, /* u64, msecs */ | ||
| 552 | NDTPA_RETRANS_TIME, /* u64, msecs */ | ||
| 553 | NDTPA_GC_STALETIME, /* u64, msecs */ | ||
| 554 | NDTPA_DELAY_PROBE_TIME, /* u64, msecs */ | ||
| 555 | NDTPA_QUEUE_LEN, /* u32 */ | ||
| 556 | NDTPA_APP_PROBES, /* u32 */ | ||
| 557 | NDTPA_UCAST_PROBES, /* u32 */ | ||
| 558 | NDTPA_MCAST_PROBES, /* u32 */ | ||
| 559 | NDTPA_ANYCAST_DELAY, /* u64, msecs */ | ||
| 560 | NDTPA_PROXY_DELAY, /* u64, msecs */ | ||
| 561 | NDTPA_PROXY_QLEN, /* u32 */ | ||
| 562 | NDTPA_LOCKTIME, /* u64, msecs */ | ||
| 563 | __NDTPA_MAX | ||
| 564 | }; | ||
| 565 | #define NDTPA_MAX (__NDTPA_MAX - 1) | ||
| 566 | |||
| 567 | struct ndtmsg | ||
| 568 | { | ||
| 569 | __u8 ndtm_family; | ||
| 570 | __u8 ndtm_pad1; | ||
| 571 | __u16 ndtm_pad2; | ||
| 572 | }; | ||
| 573 | |||
| 574 | struct ndt_config | ||
| 575 | { | ||
| 576 | __u16 ndtc_key_len; | ||
| 577 | __u16 ndtc_entry_size; | ||
| 578 | __u32 ndtc_entries; | ||
| 579 | __u32 ndtc_last_flush; /* delta to now in msecs */ | ||
| 580 | __u32 ndtc_last_rand; /* delta to now in msecs */ | ||
| 581 | __u32 ndtc_hash_rnd; | ||
| 582 | __u32 ndtc_hash_mask; | ||
| 583 | __u32 ndtc_hash_chain_gc; | ||
| 584 | __u32 ndtc_proxy_qlen; | ||
| 585 | }; | ||
| 586 | |||
| 587 | enum { | ||
| 588 | NDTA_UNSPEC, | ||
| 589 | NDTA_NAME, /* char *, unchangeable */ | ||
| 590 | NDTA_THRESH1, /* u32 */ | ||
| 591 | NDTA_THRESH2, /* u32 */ | ||
| 592 | NDTA_THRESH3, /* u32 */ | ||
| 593 | NDTA_CONFIG, /* struct ndt_config, read-only */ | ||
| 594 | NDTA_PARMS, /* nested TLV NDTPA_* */ | ||
| 595 | NDTA_STATS, /* struct ndt_stats, read-only */ | ||
| 596 | NDTA_GC_INTERVAL, /* u64, msecs */ | ||
| 597 | __NDTA_MAX | ||
| 598 | }; | ||
| 599 | #define NDTA_MAX (__NDTA_MAX - 1) | ||
| 600 | |||
| 601 | #define NDTA_RTA(r) ((struct rtattr*)(((char*)(r)) + \ | ||
| 602 | NLMSG_ALIGN(sizeof(struct ndtmsg)))) | ||
| 603 | #define NDTA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndtmsg)) | ||
| 604 | |||
| 605 | |||
| 606 | /**** | 386 | /**** |
| 607 | * General form of address family dependent message. | 387 | * General form of address family dependent message. |
| 608 | ****/ | 388 | ****/ |
| @@ -663,138 +443,6 @@ struct prefix_cacheinfo · 54 unmodified lines | |||
| 663 | __u32 valid_time; | 443 | __u32 valid_time; |
| 664 | }; | 444 | }; |
| 665 | 445 | ||
| 666 | /* The struct should be in sync with struct net_device_stats */ | ||
| 667 | struct rtnl_link_stats | ||
| 668 | { | ||
| 669 | __u32 rx_packets; /* total packets received */ | ||
| 670 | __u32 tx_packets; /* total packets transmitted */ | ||
| 671 | __u32 rx_bytes; /* total bytes received */ | ||
| 672 | __u32 tx_bytes; /* total bytes transmitted */ | ||
| 673 | __u32 rx_errors; /* bad packets received */ | ||
| 674 | __u32 tx_errors; /* packet transmit problems */ | ||
| 675 | __u32 rx_dropped; /* no space in linux buffers */ | ||
| 676 | __u32 tx_dropped; /* no space available in linux */ | ||
| 677 | __u32 multicast; /* multicast packets received */ | ||
| 678 | __u32 collisions; | ||
| 679 | |||
| 680 | /* detailed rx_errors: */ | ||
| 681 | __u32 rx_length_errors; | ||
| 682 | __u32 rx_over_errors; /* receiver ring buff overflow */ | ||
| 683 | __u32 rx_crc_errors; /* recved pkt with crc error */ | ||
| 684 | __u32 rx_frame_errors; /* recv'd frame alignment error */ | ||
| 685 | __u32 rx_fifo_errors; /* recv'r fifo overrun */ | ||
| 686 | __u32 rx_missed_errors; /* receiver missed packet */ | ||
| 687 | |||
| 688 | /* detailed tx_errors */ | ||
| 689 | __u32 tx_aborted_errors; | ||
| 690 | __u32 tx_carrier_errors; | ||
| 691 | __u32 tx_fifo_errors; | ||
| 692 | __u32 tx_heartbeat_errors; | ||
| 693 | __u32 tx_window_errors; | ||
| 694 | |||
| 695 | /* for cslip etc */ | ||
| 696 | __u32 rx_compressed; | ||
| 697 | __u32 tx_compressed; | ||
| 698 | }; | ||
| 699 | |||
| 700 | /* The struct should be in sync with struct ifmap */ | ||
| 701 | struct rtnl_link_ifmap | ||
| 702 | { | ||
| 703 | __u64 mem_start; | ||
| 704 | __u64 mem_end; | ||
| 705 | __u64 base_addr; | ||
| 706 | __u16 irq; | ||
| 707 | __u8 dma; | ||
| 708 | __u8 port; | ||
| 709 | }; | ||
| 710 | |||
| 711 | enum | ||
| 712 | { | ||
| 713 | IFLA_UNSPEC, | ||
| 714 | IFLA_ADDRESS, | ||
| 715 | IFLA_BROADCAST, | ||
| 716 | IFLA_IFNAME, | ||
| 717 | IFLA_MTU, | ||
| 718 | IFLA_LINK, | ||
| 719 | IFLA_QDISC, | ||
| 720 | IFLA_STATS, | ||
| 721 | IFLA_COST, | ||
| 722 | #define IFLA_COST IFLA_COST | ||
| 723 | IFLA_PRIORITY, | ||
| 724 | #define IFLA_PRIORITY IFLA_PRIORITY | ||
| 725 | IFLA_MASTER, | ||
| 726 | #define IFLA_MASTER IFLA_MASTER | ||
| 727 | IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */ | ||
| 728 | #define IFLA_WIRELESS IFLA_WIRELESS | ||
| 729 | IFLA_PROTINFO, /* Protocol specific information for a link */ | ||
| 730 | #define IFLA_PROTINFO IFLA_PROTINFO | ||
| 731 | IFLA_TXQLEN, | ||
| 732 | #define IFLA_TXQLEN IFLA_TXQLEN | ||
| 733 | IFLA_MAP, | ||
| 734 | #define IFLA_MAP IFLA_MAP | ||
| 735 | IFLA_WEIGHT, | ||
| 736 | #define IFLA_WEIGHT IFLA_WEIGHT | ||
| 737 | IFLA_OPERSTATE, | ||
| 738 | IFLA_LINKMODE, | ||
| 739 | __IFLA_MAX | ||
| 740 | }; | ||
| 741 | |||
| 742 | |||
| 743 | #define IFLA_MAX (__IFLA_MAX - 1) | ||
| 744 | |||
| 745 | #define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) | ||
| 746 | #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) | ||
| 747 | |||
| 748 | /* ifi_flags. | ||
| 749 | |||
| 750 | IFF_* flags. | ||
| 751 | |||
| 752 | The only change is: | ||
| 753 | IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are | ||
| 754 | more not changeable by user. They describe link media | ||
| 755 | characteristics and set by device driver. | ||
| 756 | |||
| 757 | Comments: | ||
| 758 | - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid | ||
| 759 | - If neither of these three flags are set; | ||
| 760 | the interface is NBMA. | ||
| 761 | |||
| 762 | - IFF_MULTICAST does not mean anything special: | ||
| 763 | multicasts can be used on all not-NBMA links. | ||
| 764 | IFF_MULTICAST means that this media uses special encapsulation | ||
| 765 | for multicast frames. Apparently, all IFF_POINTOPOINT and | ||
| 766 | IFF_BROADCAST devices are able to use multicasts too. | ||
| 767 | */ | ||
| 768 | |||
| 769 | /* IFLA_LINK. | ||
| 770 | For usual devices it is equal ifi_index. | ||
| 771 | If it is a "virtual interface" (f.e. tunnel), ifi_link | ||
| 772 | can point to real physical interface (f.e. for bandwidth calculations), | ||
| 773 | or maybe 0, what means, that real media is unknown (usual | ||
| 774 | for IPIP tunnels, when route to endpoint is allowed to change) | ||
| 775 | */ | ||
| 776 | |||
| 777 | /* Subtype attributes for IFLA_PROTINFO */ | ||
| 778 | enum | ||
| 779 | { | ||
| 780 | IFLA_INET6_UNSPEC, | ||
| 781 | IFLA_INET6_FLAGS, /* link flags */ | ||
| 782 | IFLA_INET6_CONF, /* sysctl parameters */ | ||
| 783 | IFLA_INET6_STATS, /* statistics */ | ||
| 784 | IFLA_INET6_MCAST, /* MC things. What of them? */ | ||
| 785 | IFLA_INET6_CACHEINFO, /* time values and max reasm size */ | ||
| 786 | __IFLA_INET6_MAX | ||
| 787 | }; | ||
| 788 | |||
| 789 | #define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1) | ||
| 790 | |||
| 791 | struct ifla_cacheinfo | ||
| 792 | { | ||
| 793 | __u32 max_reasm_len; | ||
| 794 | __u32 tstamp; /* ipv6InterfaceTable updated timestamp */ | ||
| 795 | __u32 reachable_time; | ||
| 796 | __u32 retrans_time; | ||
| 797 | }; | ||
| 798 | 446 | ||
| 799 | /***************************************************************** | 447 | /***************************************************************** |
| 800 | * Traffic control messages. | 448 | * Traffic control messages. |
| @@ -885,10 +533,13 @@ enum rtnetlink_groups { · 84 unmodified lines | |||
| 885 | RTNLGRP_NOP2, | 533 | RTNLGRP_NOP2, |
| 886 | RTNLGRP_DECnet_ROUTE, | 534 | RTNLGRP_DECnet_ROUTE, |
| 887 | #define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE | 535 | #define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE |
| 888 | RTNLGRP_NOP3, | 536 | RTNLGRP_DECnet_RULE, |
| 537 | #define RTNLGRP_DECnet_RULE RTNLGRP_DECnet_RULE | ||
| 889 | RTNLGRP_NOP4, | 538 | RTNLGRP_NOP4, |
| 890 | RTNLGRP_IPV6_PREFIX, | 539 | RTNLGRP_IPV6_PREFIX, |
| 891 | #define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX | 540 | #define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX |
| 541 | RTNLGRP_IPV6_RULE, | ||
| 542 | #define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE | ||
| 892 | __RTNLGRP_MAX | 543 | __RTNLGRP_MAX |
| 893 | }; | 544 | }; |
| 894 | #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) | 545 | #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) |
| @@ -923,8 +574,6 @@ extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, in · 28 unmodified lines | |||
| 923 | #define rtattr_parse_nested(tb, max, rta) \ | 574 | #define rtattr_parse_nested(tb, max, rta) \ |
| 924 | rtattr_parse((tb), (max), RTA_DATA((rta)), RTA_PAYLOAD((rta))) | 575 | rtattr_parse((tb), (max), RTA_DATA((rta)), RTA_PAYLOAD((rta))) |
| 925 | 576 | ||
| 926 | extern struct sock *rtnl; | ||
| 927 | |||
| 928 | struct rtnetlink_link | 577 | struct rtnetlink_link |
| 929 | { | 578 | { |
| 930 | int (*doit)(struct sk_buff *, struct nlmsghdr*, void *attr); | 579 | int (*doit)(struct sk_buff *, struct nlmsghdr*, void *attr); |
| @@ -933,6 +582,10 @@ struct rtnetlink_link · 2 unmodified lines | |||
| 933 | 582 | ||
| 934 | extern struct rtnetlink_link * rtnetlink_links[NPROTO]; | 583 | extern struct rtnetlink_link * rtnetlink_links[NPROTO]; |
| 935 | extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo); | 584 | extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo); |
| 585 | extern int rtnl_unicast(struct sk_buff *skb, u32 pid); | ||
| 586 | extern int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group, | ||
| 587 | struct nlmsghdr *nlh, gfp_t flags); | ||
| 588 | extern void rtnl_set_sk_err(u32 group, int error); | ||
| 936 | extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics); | 589 | extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics); |
| 937 | 590 | ||
| 938 | extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data); | 591 | extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data); |
| @@ -1065,6 +718,13 @@ extern void __rtnl_unlock(void); · 126 unmodified lines | |||
| 1065 | } \ | 718 | } \ |
| 1066 | } while(0) | 719 | } while(0) |
| 1067 | 720 | ||
| 721 | static inline u32 rtm_get_table(struct rtattr **rta, u8 table) | ||
| 722 | { | ||
| 723 | return RTA_GET_U32(rta[RTA_TABLE-1]); | ||
| 724 | rtattr_failure: | ||
| 725 | return table; | ||
| 726 | } | ||
| 727 | |||
| 1068 | #endif /* __KERNEL__ */ | 728 | #endif /* __KERNEL__ */ |
| 1069 | 729 | ||
| 1070 | 730 | ||
| @@ -31,6 +31,8 @@ · 30 unmodified lines | |||
| 31 | #include <linux/msg.h> | 31 | #include <linux/msg.h> |
| 32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
| 33 | #include <linux/key.h> | 33 | #include <linux/key.h> |
| 34 | #include <linux/xfrm.h> | ||
| 35 | #include <net/flow.h> | ||
| 34 | 36 | ||
| 35 | struct ctl_table; | 37 | struct ctl_table; |
| 36 | 38 | ||
| @@ -88,6 +90,7 @@ extern int cap_netlink_recv(struct sk_buff *skb, int cap); · 51 unmodified lines | |||
| 88 | struct nfsctl_arg; | 90 | struct nfsctl_arg; |
| 89 | struct sched_param; | 91 | struct sched_param; |
| 90 | struct swap_info_struct; | 92 | struct swap_info_struct; |
| 93 | struct request_sock; | ||
| 91 | 94 | ||
| 92 | /* bprm_apply_creds unsafe reasons */ | 95 | /* bprm_apply_creds unsafe reasons */ |
| 93 | #define LSM_UNSAFE_SHARE 1 | 96 | #define LSM_UNSAFE_SHARE 1 |
| @@ -812,9 +815,19 @@ struct swap_info_struct; · 718 unmodified lines | |||
| 812 | * which is used to copy security attributes between local stream sockets. | 815 | * which is used to copy security attributes between local stream sockets. |
| 813 | * @sk_free_security: | 816 | * @sk_free_security: |
| 814 | * Deallocate security structure. | 817 | * Deallocate security structure. |
| 815 | * @sk_getsid: | 818 | * @sk_clone_security: |
| 816 | * Retrieve the LSM-specific sid for the sock to enable caching of network | 819 | * Clone/copy security structure. |
| 820 | * @sk_getsecid: | ||
| 821 | * Retrieve the LSM-specific secid for the sock to enable caching of network | ||
| 817 | * authorizations. | 822 | * authorizations. |
| 823 | * @sock_graft: | ||
| 824 | * Sets the socket's isec sid to the sock's sid. | ||
| 825 | * @inet_conn_request: | ||
| 826 | * Sets the openreq's sid to socket's sid with MLS portion taken from peer sid. | ||
| 827 | * @inet_csk_clone: | ||
| 828 | * Sets the new child socket's sid to the openreq sid. | ||
| 829 | * @req_classify_flow: | ||
| 830 | * Sets the flow's sid to the openreq sid. | ||
| 818 | * | 831 | * |
| 819 | * Security hooks for XFRM operations. | 832 | * Security hooks for XFRM operations. |
| 820 | * | 833 | * |
| @@ -823,9 +836,10 @@ struct swap_info_struct; · 2 unmodified lines | |||
| 823 | * used by the XFRM system. | 836 | * used by the XFRM system. |
| 824 | * @sec_ctx contains the security context information being provided by | 837 | * @sec_ctx contains the security context information being provided by |
| 825 | * the user-level policy update program (e.g., setkey). | 838 | * the user-level policy update program (e.g., setkey). |
| 826 | * Allocate a security structure to the xp->security field. | 839 | * @sk refers to the sock from which to derive the security context. |
| 827 | * The security field is initialized to NULL when the xfrm_policy is | 840 | * Allocate a security structure to the xp->security field; the security |
| 828 | * allocated. | 841 | * field is initialized to NULL when the xfrm_policy is allocated. Only |
| 842 | * one of sec_ctx or sock can be specified. | ||
| 829 | * Return 0 if operation was successful (memory to allocate, legal context) | 843 | * Return 0 if operation was successful (memory to allocate, legal context) |
| 830 | * @xfrm_policy_clone_security: | 844 | * @xfrm_policy_clone_security: |
| 831 | * @old contains an existing xfrm_policy in the SPD. | 845 | * @old contains an existing xfrm_policy in the SPD. |
| @@ -844,9 +858,14 @@ struct swap_info_struct; · 12 unmodified lines | |||
| 844 | * Database by the XFRM system. | 858 | * Database by the XFRM system. |
| 845 | * @sec_ctx contains the security context information being provided by | 859 | * @sec_ctx contains the security context information being provided by |
| 846 | * the user-level SA generation program (e.g., setkey or racoon). | 860 | * the user-level SA generation program (e.g., setkey or racoon). |
| 847 | * Allocate a security structure to the x->security field. The | 861 | * @polsec contains the security context information associated with a xfrm |
| 848 | * security field is initialized to NULL when the xfrm_state is | 862 | * policy rule from which to take the base context. polsec must be NULL |
| 849 | * allocated. | 863 | * when sec_ctx is specified. |
| 864 | * @secid contains the secid from which to take the mls portion of the context. | ||
| 865 | * Allocate a security structure to the x->security field; the security | ||
| 866 | * field is initialized to NULL when the xfrm_state is allocated. Set the | ||
| 867 | * context to correspond to either sec_ctx or polsec, with the mls portion | ||
| 868 | * taken from secid in the latter case. | ||
| 850 | * Return 0 if operation was successful (memory to allocate, legal context). | 869 | * Return 0 if operation was successful (memory to allocate, legal context). |
| 851 | * @xfrm_state_free_security: | 870 | * @xfrm_state_free_security: |
| 852 | * @x contains the xfrm_state. | 871 | * @x contains the xfrm_state. |
| @@ -857,13 +876,27 @@ struct swap_info_struct; · 4 unmodified lines | |||
| 857 | * @xfrm_policy_lookup: | 876 | * @xfrm_policy_lookup: |
| 858 | * @xp contains the xfrm_policy for which the access control is being | 877 | * @xp contains the xfrm_policy for which the access control is being |
| 859 | * checked. | 878 | * checked. |
| 860 | * @sk_sid contains the sock security label that is used to authorize | 879 | * @fl_secid contains the flow security label that is used to authorize |
| 861 | * access to the policy xp. | 880 | * access to the policy xp. |
| 862 | * @dir contains the direction of the flow (input or output). | 881 | * @dir contains the direction of the flow (input or output). |
| 863 | * Check permission when a sock selects a xfrm_policy for processing | 882 | * Check permission when a flow selects a xfrm_policy for processing |
| 864 | * XFRMs on a packet. The hook is called when selecting either a | 883 | * XFRMs on a packet. The hook is called when selecting either a |
| 865 | * per-socket policy or a generic xfrm policy. | 884 | * per-socket policy or a generic xfrm policy. |
| 866 | * Return 0 if permission is granted. | 885 | * Return 0 if permission is granted. |
| 886 | * @xfrm_state_pol_flow_match: | ||
| 887 | * @x contains the state to match. | ||
| 888 | * @xp contains the policy to check for a match. | ||
| 889 | * @fl contains the flow to check for a match. | ||
| 890 | * Return 1 if there is a match. | ||
| 891 | * @xfrm_flow_state_match: | ||
| 892 | * @fl contains the flow key to match. | ||
| 893 | * @xfrm points to the xfrm_state to match. | ||
| 894 | * Return 1 if there is a match. | ||
| 895 | * @xfrm_decode_session: | ||
| 896 | * @skb points to skb to decode. | ||
| 897 | * @secid points to the flow key secid to set. | ||
| 898 | * @ckall says if all xfrms used should be checked for same secid. | ||
| 899 | * Return 0 if ckall is zero or all xfrms used have the same secid. | ||
| 867 | * | 900 | * |
| 868 | * Security hooks affecting all Key Management operations | 901 | * Security hooks affecting all Key Management operations |
| 869 | * | 902 | * |
| @@ -1308,8 +1341,8 @@ struct security_operations { · 438 unmodified lines | |||
| 1308 | int (*unix_may_send) (struct socket * sock, struct socket * other); | 1341 | int (*unix_may_send) (struct socket * sock, struct socket * other); |
| 1309 | 1342 | ||
| 1310 | int (*socket_create) (int family, int type, int protocol, int kern); | 1343 | int (*socket_create) (int family, int type, int protocol, int kern); |
| 1311 | void (*socket_post_create) (struct socket * sock, int family, | 1344 | int (*socket_post_create) (struct socket * sock, int family, |
| 1312 | int type, int protocol, int kern); | 1345 | int type, int protocol, int kern); |
| 1313 | int (*socket_bind) (struct socket * sock, | 1346 | int (*socket_bind) (struct socket * sock, |
| 1314 | struct sockaddr * address, int addrlen); | 1347 | struct sockaddr * address, int addrlen); |
| 1315 | int (*socket_connect) (struct socket * sock, | 1348 | int (*socket_connect) (struct socket * sock, |
| @@ -1332,18 +1365,31 @@ struct security_operations { · 16 unmodified lines | |||
| 1332 | int (*socket_getpeersec_dgram) (struct socket *sock, struct sk_buff *skb, u32 *secid); | 1365 | int (*socket_getpeersec_dgram) (struct socket *sock, struct sk_buff *skb, u32 *secid); |
| 1333 | int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority); | 1366 | int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority); |
| 1334 | void (*sk_free_security) (struct sock *sk); | 1367 | void (*sk_free_security) (struct sock *sk); |
| 1335 | unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir); | 1368 | void (*sk_clone_security) (const struct sock *sk, struct sock *newsk); |
| 1369 | void (*sk_getsecid) (struct sock *sk, u32 *secid); | ||
| 1370 | void (*sock_graft)(struct sock* sk, struct socket *parent); | ||
| 1371 | int (*inet_conn_request)(struct sock *sk, struct sk_buff *skb, | ||
| 1372 | struct request_sock *req); | ||
| 1373 | void (*inet_csk_clone)(struct sock *newsk, const struct request_sock *req); | ||
| 1374 | void (*req_classify_flow)(const struct request_sock *req, struct flowi *fl); | ||
| 1336 | #endif /* CONFIG_SECURITY_NETWORK */ | 1375 | #endif /* CONFIG_SECURITY_NETWORK */ |
| 1337 | 1376 | ||
| 1338 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1377 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
| 1339 | int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx); | 1378 | int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, |
| 1379 | struct xfrm_user_sec_ctx *sec_ctx, struct sock *sk); | ||
| 1340 | int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new); | 1380 | int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new); |
| 1341 | void (*xfrm_policy_free_security) (struct xfrm_policy *xp); | 1381 | void (*xfrm_policy_free_security) (struct xfrm_policy *xp); |
| 1342 | int (*xfrm_policy_delete_security) (struct xfrm_policy *xp); | 1382 | int (*xfrm_policy_delete_security) (struct xfrm_policy *xp); |
| 1343 | int (*xfrm_state_alloc_security) (struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx); | 1383 | int (*xfrm_state_alloc_security) (struct xfrm_state *x, |
| 1384 | struct xfrm_user_sec_ctx *sec_ctx, struct xfrm_sec_ctx *polsec, | ||
| 1385 | u32 secid); | ||
| 1344 | void (*xfrm_state_free_security) (struct xfrm_state *x); | 1386 | void (*xfrm_state_free_security) (struct xfrm_state *x); |
| 1345 | int (*xfrm_state_delete_security) (struct xfrm_state *x); | 1387 | int (*xfrm_state_delete_security) (struct xfrm_state *x); |
| 1346 | int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 sk_sid, u8 dir); | 1388 | int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 fl_secid, u8 dir); |
| 1389 | int (*xfrm_state_pol_flow_match)(struct xfrm_state *x, | ||
| 1390 | struct xfrm_policy *xp, struct flowi *fl); | ||
| 1391 | int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm); | ||
| 1392 | int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall); | ||
| 1347 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | 1393 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ |
| 1348 | 1394 | ||
| 1349 | /* key management security hooks */ | 1395 | /* key management security hooks */ |
| @@ -2778,13 +2824,13 @@ static inline int security_socket_create (int family, int type, · 1428 unmodified lines | |||
| 2778 | return security_ops->socket_create(family, type, protocol, kern); | 2824 | return security_ops->socket_create(family, type, protocol, kern); |
| 2779 | } | 2825 | } |
| 2780 | 2826 | ||
| 2781 | static inline void security_socket_post_create(struct socket * sock, | 2827 | static inline int security_socket_post_create(struct socket * sock, |
| 2782 | int family, | 2828 | int family, |
| 2783 | int type, | 2829 | int type, |
| 2784 | int protocol, int kern) | 2830 | int protocol, int kern) |
| 2785 | { | 2831 | { |
| 2786 | security_ops->socket_post_create(sock, family, type, | 2832 | return security_ops->socket_post_create(sock, family, type, |
| 2787 | protocol, kern); | 2833 | protocol, kern); |
| 2788 | } | 2834 | } |
| 2789 | 2835 | ||
| 2790 | static inline int security_socket_bind(struct socket * sock, | 2836 | static inline int security_socket_bind(struct socket * sock, |
| @@ -2885,9 +2931,36 @@ static inline void security_sk_free(struct sock *sk) · 94 unmodified lines | |||
| 2885 | return security_ops->sk_free_security(sk); | 2931 | return security_ops->sk_free_security(sk); |
| 2886 | } | 2932 | } |
| 2887 | 2933 | ||
| 2888 | static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir) | 2934 | static inline void security_sk_clone(const struct sock *sk, struct sock *newsk) |
| 2935 | { | ||
| 2936 | return security_ops->sk_clone_security(sk, newsk); | ||
| 2937 | } | ||
| 2938 | |||
| 2939 | static inline void security_sk_classify_flow(struct sock *sk, struct flowi *fl) | ||
| 2889 | { | 2940 | { |
| 2890 | return security_ops->sk_getsid(sk, fl, dir); | 2941 | security_ops->sk_getsecid(sk, &fl->secid); |
| 2942 | } | ||
| 2943 | |||
| 2944 | static inline void security_req_classify_flow(const struct request_sock *req, struct flowi *fl) | ||
| 2945 | { | ||
| 2946 | security_ops->req_classify_flow(req, fl); | ||
| 2947 | } | ||
| 2948 | |||
| 2949 | static inline void security_sock_graft(struct sock* sk, struct socket *parent) | ||
| 2950 | { | ||
| 2951 | security_ops->sock_graft(sk, parent); | ||
| 2952 | } | ||
| 2953 | |||
| 2954 | static inline int security_inet_conn_request(struct sock *sk, | ||
| 2955 | struct sk_buff *skb, struct request_sock *req) | ||
| 2956 | { | ||
| 2957 | return security_ops->inet_conn_request(sk, skb, req); | ||
| 2958 | } | ||
| 2959 | |||
| 2960 | static inline void security_inet_csk_clone(struct sock *newsk, | ||
| 2961 | const struct request_sock *req) | ||
| 2962 | { | ||
| 2963 | security_ops->inet_csk_clone(newsk, req); | ||
| 2891 | } | 2964 | } |
| 2892 | #else /* CONFIG_SECURITY_NETWORK */ | 2965 | #else /* CONFIG_SECURITY_NETWORK */ |
| 2893 | static inline int security_unix_stream_connect(struct socket * sock, | 2966 | static inline int security_unix_stream_connect(struct socket * sock, |
| @@ -2909,11 +2982,12 @@ static inline int security_socket_create (int family, int type, · 15 unmodified lines | |||
| 2909 | return 0; | 2982 | return 0; |
| 2910 | } | 2983 | } |
| 2911 | 2984 | ||
| 2912 | static inline void security_socket_post_create(struct socket * sock, | 2985 | static inline int security_socket_post_create(struct socket * sock, |
| 2913 | int family, | 2986 | int family, |
| 2914 | int type, | 2987 | int type, |
| 2915 | int protocol, int kern) | 2988 | int protocol, int kern) |
| 2916 | { | 2989 | { |
| 2990 | return 0; | ||
| 2917 | } | 2991 | } |
| 2918 | 2992 | ||
| 2919 | static inline int security_socket_bind(struct socket * sock, | 2993 | static inline int security_socket_bind(struct socket * sock, |
| @@ -3011,16 +3085,43 @@ static inline void security_sk_free(struct sock *sk) · 91 unmodified lines | |||
| 3011 | { | 3085 | { |
| 3012 | } | 3086 | } |
| 3013 | 3087 | ||
| 3014 | static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir) | 3088 | static inline void security_sk_clone(const struct sock *sk, struct sock *newsk) |
| 3089 | { | ||
| 3090 | } | ||
| 3091 | |||
| 3092 | static inline void security_sk_classify_flow(struct sock *sk, struct flowi *fl) | ||
| 3093 | { | ||
| 3094 | } | ||
| 3095 | |||
| 3096 | static inline void security_req_classify_flow(const struct request_sock *req, struct flowi *fl) | ||
| 3097 | { | ||
| 3098 | } | ||
| 3099 | |||
| 3100 | static inline void security_sock_graft(struct sock* sk, struct socket *parent) | ||
| 3101 | { | ||
| 3102 | } | ||
| 3103 | |||
| 3104 | static inline int security_inet_conn_request(struct sock *sk, | ||
| 3105 | struct sk_buff *skb, struct request_sock *req) | ||
| 3015 | { | 3106 | { |
| 3016 | return 0; | 3107 | return 0; |
| 3017 | } | 3108 | } |
| 3109 | |||
| 3110 | static inline void security_inet_csk_clone(struct sock *newsk, | ||
| 3111 | const struct request_sock *req) | ||
| 3112 | { | ||
| 3113 | } | ||
| 3018 | #endif /* CONFIG_SECURITY_NETWORK */ | 3114 | #endif /* CONFIG_SECURITY_NETWORK */ |
| 3019 | 3115 | ||
| 3020 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 3116 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
| 3021 | static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) | 3117 | static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) |
| 3022 | { | 3118 | { |
| 3023 | return security_ops->xfrm_policy_alloc_security(xp, sec_ctx); | 3119 | return security_ops->xfrm_policy_alloc_security(xp, sec_ctx, NULL); |
| 3120 | } | ||
| 3121 | |||
| 3122 | static inline int security_xfrm_sock_policy_alloc(struct xfrm_policy *xp, struct sock *sk) | ||
| 3123 | { | ||
| 3124 | return security_ops->xfrm_policy_alloc_security(xp, NULL, sk); | ||
| 3024 | } | 3125 | } |
| 3025 | 3126 | ||
| 3026 | static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) | 3127 | static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) |
| @@ -3038,9 +3139,18 @@ static inline int security_xfrm_policy_delete(struct xfrm_policy *xp) · 11 unmodified lines | |||
| 3038 | return security_ops->xfrm_policy_delete_security(xp); | 3139 | return security_ops->xfrm_policy_delete_security(xp); |
| 3039 | } | 3140 | } |
| 3040 | 3141 | ||
| 3041 | static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) | 3142 | static inline int security_xfrm_state_alloc(struct xfrm_state *x, |
| 3143 | struct xfrm_user_sec_ctx *sec_ctx) | ||
| 3042 | { | 3144 | { |
| 3043 | return security_ops->xfrm_state_alloc_security(x, sec_ctx); | 3145 | return security_ops->xfrm_state_alloc_security(x, sec_ctx, NULL, 0); |
| 3146 | } | ||
| 3147 | |||
| 3148 | static inline int security_xfrm_state_alloc_acquire(struct xfrm_state *x, | ||
| 3149 | struct xfrm_sec_ctx *polsec, u32 secid) | ||
| 3150 | { | ||
| 3151 | if (!polsec) | ||
| 3152 | return 0; | ||
| 3153 | return security_ops->xfrm_state_alloc_security(x, NULL, polsec, secid); | ||
| 3044 | } | 3154 | } |
| 3045 | 3155 | ||
| 3046 | static inline int security_xfrm_state_delete(struct xfrm_state *x) | 3156 | static inline int security_xfrm_state_delete(struct xfrm_state *x) |
| @@ -3053,9 +3163,32 @@ static inline void security_xfrm_state_free(struct xfrm_state *x) · 6 unmodified lines | |||
| 3053 | security_ops->xfrm_state_free_security(x); | 3163 | security_ops->xfrm_state_free_security(x); |
| 3054 | } | 3164 | } |
| 3055 | 3165 | ||
| 3056 | static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) | 3166 | static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) |
| 3167 | { | ||
| 3168 | return security_ops->xfrm_policy_lookup(xp, fl_secid, dir); | ||
| 3169 | } | ||
| 3170 | |||
| 3171 | static inline int security_xfrm_state_pol_flow_match(struct xfrm_state *x, | ||
| 3172 | struct xfrm_policy *xp, struct flowi *fl) | ||
| 3057 | { | 3173 | { |
| 3058 | return security_ops->xfrm_policy_lookup(xp, sk_sid, dir); | 3174 | return security_ops->xfrm_state_pol_flow_match(x, xp, fl); |
| 3175 | } | ||
| 3176 | |||
| 3177 | static inline int security_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) | ||
| 3178 | { | ||
| 3179 | return security_ops->xfrm_flow_state_match(fl, xfrm); | ||
| 3180 | } | ||
| 3181 | |||
| 3182 | static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) | ||
| 3183 | { | ||
| 3184 | return security_ops->xfrm_decode_session(skb, secid, 1); | ||
| 3185 | } | ||
| 3186 | |||
| 3187 | static inline void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl) | ||
| 3188 | { | ||
| 3189 | int rc = security_ops->xfrm_decode_session(skb, &fl->secid, 0); | ||
| 3190 | |||
| 3191 | BUG_ON(rc); | ||
| 3059 | } | 3192 | } |
| 3060 | #else /* CONFIG_SECURITY_NETWORK_XFRM */ | 3193 | #else /* CONFIG_SECURITY_NETWORK_XFRM */ |
| 3061 | static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) | 3194 | static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) |
| @@ -3063,6 +3196,11 @@ static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm · 1 unmodified line | |||
| 3063 | return 0; | 3196 | return 0; |
| 3064 | } | 3197 | } |
| 3065 | 3198 | ||
| 3199 | static inline int security_xfrm_sock_policy_alloc(struct xfrm_policy *xp, struct sock *sk) | ||
| 3200 | { | ||
| 3201 | return 0; | ||
| 3202 | } | ||
| 3203 | |||
| 3066 | static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) | 3204 | static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) |
| 3067 | { | 3205 | { |
| 3068 | return 0; | 3206 | return 0; |
| @@ -3077,7 +3215,14 @@ static inline int security_xfrm_policy_delete(struct xfrm_policy *xp) · 8 unmodified lines | |||
| 3077 | return 0; | 3215 | return 0; |
| 3078 | } | 3216 | } |
| 3079 | 3217 | ||
| 3080 | static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) | 3218 | static inline int security_xfrm_state_alloc(struct xfrm_state *x, |
| 3219 | struct xfrm_user_sec_ctx *sec_ctx) | ||
| 3220 | { | ||
| 3221 | return 0; | ||
| 3222 | } | ||
| 3223 | |||
| 3224 | static inline int security_xfrm_state_alloc_acquire(struct xfrm_state *x, | ||
| 3225 | struct xfrm_sec_ctx *polsec, u32 secid) | ||
| 3081 | { | 3226 | { |
| 3082 | return 0; | 3227 | return 0; |
| 3083 | } | 3228 | } |
| @@ -3091,10 +3236,32 @@ static inline int security_xfrm_state_delete(struct xfrm_state *x) · 7 unmodified lines | |||
| 3091 | return 0; | 3236 | return 0; |
| 3092 | } | 3237 | } |
| 3093 | 3238 | ||
| 3094 | static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) | 3239 | static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) |
| 3240 | { | ||
| 3241 | return 0; | ||
| 3242 | } | ||
| 3243 | |||
| 3244 | static inline int security_xfrm_state_pol_flow_match(struct xfrm_state *x, | ||
| 3245 | struct xfrm_policy *xp, struct flowi *fl) | ||
| 3246 | { | ||
| 3247 | return 1; | ||
| 3248 | } | ||
| 3249 | |||
| 3250 | static inline int security_xfrm_flow_state_match(struct flowi *fl, | ||
| 3251 | struct xfrm_state *xfrm) | ||
| 3252 | { | ||
| 3253 | return 1; | ||
| 3254 | } | ||
| 3255 | |||
| 3256 | static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) | ||
| 3095 | { | 3257 | { |
| 3096 | return 0; | 3258 | return 0; |
| 3097 | } | 3259 | } |
| 3260 | |||
| 3261 | static inline void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl) | ||
| 3262 | { | ||
| 3263 | } | ||
| 3264 | |||
| 3098 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | 3265 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ |
| 3099 | 3266 | ||
| 3100 | #ifdef CONFIG_KEYS | 3267 | #ifdef CONFIG_KEYS |
| @@ -34,8 +34,9 @@ · 33 unmodified lines | |||
| 34 | #define HAVE_ALIGNABLE_SKB /* Ditto 8) */ | 34 | #define HAVE_ALIGNABLE_SKB /* Ditto 8) */ |
| 35 | 35 | ||
| 36 | #define CHECKSUM_NONE 0 | 36 | #define CHECKSUM_NONE 0 |
| 37 | #define CHECKSUM_HW 1 | 37 | #define CHECKSUM_PARTIAL 1 |
| 38 | #define CHECKSUM_UNNECESSARY 2 | 38 | #define CHECKSUM_UNNECESSARY 2 |
| 39 | #define CHECKSUM_COMPLETE 3 | ||
| 39 | 40 | ||
| 40 | #define SKB_DATA_ALIGN(X) (((X) + (SMP_CACHE_BYTES - 1)) & \ | 41 | #define SKB_DATA_ALIGN(X) (((X) + (SMP_CACHE_BYTES - 1)) & \ |
| 41 | ~(SMP_CACHE_BYTES - 1)) | 42 | ~(SMP_CACHE_BYTES - 1)) |
| @@ -56,17 +57,17 @@ · 14 unmodified lines | |||
| 56 | * Apparently with secret goal to sell you new device, when you | 57 | * Apparently with secret goal to sell you new device, when you |
| 57 | * will add new protocol to your host. F.e. IPv6. 8) | 58 | * will add new protocol to your host. F.e. IPv6. 8) |
| 58 | * | 59 | * |
| 59 | * HW: the most generic way. Device supplied checksum of _all_ | 60 | * COMPLETE: the most generic way. Device supplied checksum of _all_ |
| 60 | * the packet as seen by netif_rx in skb->csum. | 61 | * the packet as seen by netif_rx in skb->csum. |
| 61 | * NOTE: Even if device supports only some protocols, but | 62 | * NOTE: Even if device supports only some protocols, but |
| 62 | * is able to produce some skb->csum, it MUST use HW, | 63 | * is able to produce some skb->csum, it MUST use COMPLETE, |
| 63 | * not UNNECESSARY. | 64 | * not UNNECESSARY. |
| 64 | * | 65 | * |
| 65 | * B. Checksumming on output. | 66 | * B. Checksumming on output. |
| 66 | * | 67 | * |
| 67 | * NONE: skb is checksummed by protocol or csum is not required. | 68 | * NONE: skb is checksummed by protocol or csum is not required. |
| 68 | * | 69 | * |
| 69 | * HW: device is required to csum packet as seen by hard_start_xmit | 70 | * PARTIAL: device is required to csum packet as seen by hard_start_xmit |
| 70 | * from skb->h.raw to the end and to record the checksum | 71 | * from skb->h.raw to the end and to record the checksum |
| 71 | * at skb->h.raw+skb->csum. | 72 | * at skb->h.raw+skb->csum. |
| 72 | * | 73 | * |
| @@ -1261,14 +1262,14 @@ static inline int skb_linearize_cow(struct sk_buff *skb) · 1188 unmodified lines | |||
| 1261 | * @len: length of data pulled | 1262 | * @len: length of data pulled |
| 1262 | * | 1263 | * |
| 1263 | * After doing a pull on a received packet, you need to call this to | 1264 | * After doing a pull on a received packet, you need to call this to |
| 1264 | * update the CHECKSUM_HW checksum, or set ip_summed to CHECKSUM_NONE | 1265 | * update the CHECKSUM_COMPLETE checksum, or set ip_summed to |
| 1265 | * so that it can be recomputed from scratch. | 1266 | * CHECKSUM_NONE so that it can be recomputed from scratch. |
| 1266 | */ | 1267 | */ |
| 1267 | 1268 | ||
| 1268 | static inline void skb_postpull_rcsum(struct sk_buff *skb, | 1269 | static inline void skb_postpull_rcsum(struct sk_buff *skb, |
| 1269 | const void *start, unsigned int len) | 1270 | const void *start, unsigned int len) |
| 1270 | { | 1271 | { |
| 1271 | if (skb->ip_summed == CHECKSUM_HW) | 1272 | if (skb->ip_summed == CHECKSUM_COMPLETE) |
| 1272 | skb->csum = csum_sub(skb->csum, csum_partial(start, len, 0)); | 1273 | skb->csum = csum_sub(skb->csum, csum_partial(start, len, 0)); |
| 1273 | } | 1274 | } |
| 1274 | 1275 | ||
| @@ -1287,7 +1288,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) · 12 unmodified lines | |||
| 1287 | { | 1288 | { |
| 1288 | if (likely(len >= skb->len)) | 1289 | if (likely(len >= skb->len)) |
| 1289 | return 0; | 1290 | return 0; |
| 1290 | if (skb->ip_summed == CHECKSUM_HW) | 1291 | if (skb->ip_summed == CHECKSUM_COMPLETE) |
| 1291 | skb->ip_summed = CHECKSUM_NONE; | 1292 | skb->ip_summed = CHECKSUM_NONE; |
| 1292 | return __pskb_trim(skb, len); | 1293 | return __pskb_trim(skb, len); |
| 1293 | } | 1294 | } |
| @@ -155,42 +155,11 @@ enum · 154 unmodified lines | |||
| 155 | UDP_MIB_NOPORTS, /* NoPorts */ | 155 | UDP_MIB_NOPORTS, /* NoPorts */ |
| 156 | UDP_MIB_INERRORS, /* InErrors */ | 156 | UDP_MIB_INERRORS, /* InErrors */ |
| 157 | UDP_MIB_OUTDATAGRAMS, /* OutDatagrams */ | 157 | UDP_MIB_OUTDATAGRAMS, /* OutDatagrams */ |
| 158 | UDP_MIB_RCVBUFERRORS, /* RcvbufErrors */ | ||
| 159 | UDP_MIB_SNDBUFERRORS, /* SndbufErrors */ | ||
| 158 | __UDP_MIB_MAX | 160 | __UDP_MIB_MAX |
| 159 | }; | 161 | }; |
| 160 | 162 | ||
| 161 | /* sctp mib definitions */ | ||
| 162 | /* | ||
| 163 | * draft-ietf-sigtran-sctp-mib-07.txt | ||
| 164 | */ | ||
| 165 | enum | ||
| 166 | { | ||
| 167 | SCTP_MIB_NUM = 0, | ||
| 168 | SCTP_MIB_CURRESTAB, /* CurrEstab */ | ||
| 169 | SCTP_MIB_ACTIVEESTABS, /* ActiveEstabs */ | ||
| 170 | SCTP_MIB_PASSIVEESTABS, /* PassiveEstabs */ | ||
| 171 | SCTP_MIB_ABORTEDS, /* Aborteds */ | ||
| 172 | SCTP_MIB_SHUTDOWNS, /* Shutdowns */ | ||
| 173 | SCTP_MIB_OUTOFBLUES, /* OutOfBlues */ | ||
| 174 | SCTP_MIB_CHECKSUMERRORS, /* ChecksumErrors */ | ||
| 175 | SCTP_MIB_OUTCTRLCHUNKS, /* OutCtrlChunks */ | ||
| 176 | SCTP_MIB_OUTORDERCHUNKS, /* OutOrderChunks */ | ||
| 177 | SCTP_MIB_OUTUNORDERCHUNKS, /* OutUnorderChunks */ | ||
| 178 | SCTP_MIB_INCTRLCHUNKS, /* InCtrlChunks */ | ||
| 179 | SCTP_MIB_INORDERCHUNKS, /* InOrderChunks */ | ||
| 180 | SCTP_MIB_INUNORDERCHUNKS, /* InUnorderChunks */ | ||
| 181 | SCTP_MIB_FRAGUSRMSGS, /* FragUsrMsgs */ | ||
| 182 | SCTP_MIB_REASMUSRMSGS, /* ReasmUsrMsgs */ | ||
| 183 | SCTP_MIB_OUTSCTPPACKS, /* OutSCTPPacks */ | ||
| 184 | SCTP_MIB_INSCTPPACKS, /* InSCTPPacks */ | ||
| 185 | SCTP_MIB_RTOALGORITHM, /* RtoAlgorithm */ | ||
| 186 | SCTP_MIB_RTOMIN, /* RtoMin */ | ||
| 187 | SCTP_MIB_RTOMAX, /* RtoMax */ | ||
| 188 | SCTP_MIB_RTOINITIAL, /* RtoInitial */ | ||
| 189 | SCTP_MIB_VALCOOKIELIFE, /* ValCookieLife */ | ||
| 190 | SCTP_MIB_MAXINITRETR, /* MaxInitRetr */ | ||
| 191 | __SCTP_MIB_MAX | ||
| 192 | }; | ||
| 193 | |||
| 194 | /* linux mib definitions */ | 163 | /* linux mib definitions */ |
| 195 | enum | 164 | enum |
| 196 | { | 165 | { |
| @@ -18,18 +18,6 @@ · 17 unmodified lines | |||
| 18 | #include <linux/sunrpc/timer.h> | 18 | #include <linux/sunrpc/timer.h> |
| 19 | #include <asm/signal.h> | 19 | #include <asm/signal.h> |
| 20 | 20 | ||
| 21 | /* | ||
| 22 | * This defines an RPC port mapping | ||
| 23 | */ | ||
| 24 | struct rpc_portmap { | ||
| 25 | __u32 pm_prog; | ||
| 26 | __u32 pm_vers; | ||
| 27 | __u32 pm_prot; | ||
| 28 | __u16 pm_port; | ||
| 29 | unsigned char pm_binding : 1; /* doing a getport() */ | ||
| 30 | struct rpc_wait_queue pm_bindwait; /* waiting on getport() */ | ||
| 31 | }; | ||
| 32 | |||
| 33 | struct rpc_inode; | 21 | struct rpc_inode; |
| 34 | 22 | ||
| 35 | /* | 23 | /* |
| @@ -40,7 +28,9 @@ struct rpc_clnt { · 4 unmodified lines | |||
| 40 | atomic_t cl_users; /* number of references */ | 28 | atomic_t cl_users; /* number of references */ |
| 41 | struct rpc_xprt * cl_xprt; /* transport */ | 29 | struct rpc_xprt * cl_xprt; /* transport */ |
| 42 | struct rpc_procinfo * cl_procinfo; /* procedure info */ | 30 | struct rpc_procinfo * cl_procinfo; /* procedure info */ |
| 43 | u32 cl_maxproc; /* max procedure number */ | 31 | u32 cl_prog, /* RPC program number */ |
| 32 | cl_vers, /* RPC version number */ | ||
| 33 | cl_maxproc; /* max procedure number */ | ||
| 44 | 34 | ||
| 45 | char * cl_server; /* server machine name */ | 35 | char * cl_server; /* server machine name */ |
| 46 | char * cl_protname; /* protocol name */ | 36 | char * cl_protname; /* protocol name */ |
| @@ -55,7 +45,6 @@ struct rpc_clnt { · 8 unmodified lines | |||
| 55 | cl_dead : 1;/* abandoned */ | 45 | cl_dead : 1;/* abandoned */ |
| 56 | 46 | ||
| 57 | struct rpc_rtt * cl_rtt; /* RTO estimator data */ | 47 | struct rpc_rtt * cl_rtt; /* RTO estimator data */ |
| 58 | struct rpc_portmap * cl_pmap; /* port mapping */ | ||
| 59 | 48 | ||
| 60 | int cl_nodelen; /* nodename length */ | 49 | int cl_nodelen; /* nodename length */ |
| 61 | char cl_nodename[UNX_MAXNODENAME]; | 50 | char cl_nodename[UNX_MAXNODENAME]; |
| @@ -64,14 +53,8 @@ struct rpc_clnt { · 2 unmodified lines | |||
| 64 | struct dentry * cl_dentry; /* inode */ | 53 | struct dentry * cl_dentry; /* inode */ |
| 65 | struct rpc_clnt * cl_parent; /* Points to parent of clones */ | 54 | struct rpc_clnt * cl_parent; /* Points to parent of clones */ |
| 66 | struct rpc_rtt cl_rtt_default; | 55 | struct rpc_rtt cl_rtt_default; |
| 67 | struct rpc_portmap cl_pmap_default; | ||
| 68 | char cl_inline_name[32]; | 56 | char cl_inline_name[32]; |
| 69 | }; | 57 | }; |
| 70 | #define cl_timeout cl_xprt->timeout | ||
| 71 | #define cl_prog cl_pmap->pm_prog | ||
| 72 | #define cl_vers cl_pmap->pm_vers | ||
| 73 | #define cl_port cl_pmap->pm_port | ||
| 74 | #define cl_prot cl_pmap->pm_prot | ||
| 75 | 58 | ||
| 76 | /* | 59 | /* |
| 77 | * General RPC program info | 60 | * General RPC program info |
| @@ -106,24 +89,36 @@ struct rpc_procinfo { · 28 unmodified lines | |||
| 106 | char * p_name; /* name of procedure */ | 89 | char * p_name; /* name of procedure */ |
| 107 | }; | 90 | }; |
| 108 | 91 | ||
| 109 | #define RPC_CONGESTED(clnt) (RPCXPRT_CONGESTED((clnt)->cl_xprt)) | ||
| 110 | #define RPC_PEERADDR(clnt) (&(clnt)->cl_xprt->addr) | ||
| 111 | |||
| 112 | #ifdef __KERNEL__ | 92 | #ifdef __KERNEL__ |
| 113 | 93 | ||
| 114 | struct rpc_clnt *rpc_create_client(struct rpc_xprt *xprt, char *servname, | 94 | struct rpc_create_args { |
| 115 | struct rpc_program *info, | 95 | int protocol; |
| 116 | u32 version, rpc_authflavor_t authflavor); | 96 | struct sockaddr *address; |
| 117 | struct rpc_clnt *rpc_new_client(struct rpc_xprt *xprt, char *servname, | 97 | size_t addrsize; |
| 118 | struct rpc_program *info, | 98 | struct rpc_timeout *timeout; |
| 119 | u32 version, rpc_authflavor_t authflavor); | 99 | char *servername; |
| 100 | struct rpc_program *program; | ||
| 101 | u32 version; | ||
| 102 | rpc_authflavor_t authflavor; | ||
| 103 | unsigned long flags; | ||
| 104 | }; | ||
| 105 | |||
| 106 | /* Values for "flags" field */ | ||
| 107 | #define RPC_CLNT_CREATE_HARDRTRY (1UL << 0) | ||
| 108 | #define RPC_CLNT_CREATE_INTR (1UL << 1) | ||
| 109 | #define RPC_CLNT_CREATE_AUTOBIND (1UL << 2) | ||
| 110 | #define RPC_CLNT_CREATE_ONESHOT (1UL << 3) | ||
| 111 | #define RPC_CLNT_CREATE_NONPRIVPORT (1UL << 4) | ||
| 112 | #define RPC_CLNT_CREATE_NOPING (1UL << 5) | ||
| 113 | |||
| 114 | struct rpc_clnt *rpc_create(struct rpc_create_args *args); | ||
| 120 | struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *, | 115 | struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *, |
| 121 | struct rpc_program *, int); | 116 | struct rpc_program *, int); |
| 122 | struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); | 117 | struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); |
| 123 | int rpc_shutdown_client(struct rpc_clnt *); | 118 | int rpc_shutdown_client(struct rpc_clnt *); |
| 124 | int rpc_destroy_client(struct rpc_clnt *); | 119 | int rpc_destroy_client(struct rpc_clnt *); |
| 125 | void rpc_release_client(struct rpc_clnt *); | 120 | void rpc_release_client(struct rpc_clnt *); |
| 126 | void rpc_getport(struct rpc_task *, struct rpc_clnt *); | 121 | void rpc_getport(struct rpc_task *); |
| 127 | int rpc_register(u32, u32, int, unsigned short, int *); | 122 | int rpc_register(u32, u32, int, unsigned short, int *); |
| 128 | 123 | ||
| 129 | void rpc_call_setup(struct rpc_task *, struct rpc_message *, int); | 124 | void rpc_call_setup(struct rpc_task *, struct rpc_message *, int); |
| @@ -140,6 +135,8 @@ void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int); · 10 unmodified lines | |||
| 140 | size_t rpc_max_payload(struct rpc_clnt *); | 135 | size_t rpc_max_payload(struct rpc_clnt *); |
| 141 | void rpc_force_rebind(struct rpc_clnt *); | 136 | void rpc_force_rebind(struct rpc_clnt *); |
| 142 | int rpc_ping(struct rpc_clnt *clnt, int flags); | 137 | int rpc_ping(struct rpc_clnt *clnt, int flags); |
| 138 | size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t); | ||
| 139 | char * rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t); | ||
| 143 | 140 | ||
| 144 | /* | 141 | /* |
| 145 | * Helper function for NFSroot support | 142 | * Helper function for NFSroot support |
| @@ -43,7 +43,7 @@ extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *); · 42 unmodified lines | |||
| 43 | 43 | ||
| 44 | extern struct dentry *rpc_mkdir(char *, struct rpc_clnt *); | 44 | extern struct dentry *rpc_mkdir(char *, struct rpc_clnt *); |
| 45 | extern int rpc_rmdir(struct dentry *); | 45 | extern int rpc_rmdir(struct dentry *); |
| 46 | extern struct dentry *rpc_mkpipe(char *, void *, struct rpc_pipe_ops *, int flags); | 46 | extern struct dentry *rpc_mkpipe(struct dentry *, const char *, void *, struct rpc_pipe_ops *, int flags); |
| 47 | extern int rpc_unlink(struct dentry *); | 47 | extern int rpc_unlink(struct dentry *); |
| 48 | extern struct vfsmount *rpc_get_mount(void); | 48 | extern struct vfsmount *rpc_get_mount(void); |
| 49 | extern void rpc_put_mount(void); | 49 | extern void rpc_put_mount(void); |
| @@ -127,7 +127,6 @@ struct rpc_call_ops { · 126 unmodified lines | |||
| 127 | */ | 127 | */ |
| 128 | #define RPC_TASK_ASYNC 0x0001 /* is an async task */ | 128 | #define RPC_TASK_ASYNC 0x0001 /* is an async task */ |
| 129 | #define RPC_TASK_SWAPPER 0x0002 /* is swapping in/out */ | 129 | #define RPC_TASK_SWAPPER 0x0002 /* is swapping in/out */ |
| 130 | #define RPC_TASK_CHILD 0x0008 /* is child of other task */ | ||
| 131 | #define RPC_CALL_MAJORSEEN 0x0020 /* major timeout seen */ | 130 | #define RPC_CALL_MAJORSEEN 0x0020 /* major timeout seen */ |
| 132 | #define RPC_TASK_ROOTCREDS 0x0040 /* force root creds */ | 131 | #define RPC_TASK_ROOTCREDS 0x0040 /* force root creds */ |
| 133 | #define RPC_TASK_DYNAMIC 0x0080 /* task was kmalloc'ed */ | 132 | #define RPC_TASK_DYNAMIC 0x0080 /* task was kmalloc'ed */ |
| @@ -136,7 +135,6 @@ struct rpc_call_ops { · 2 unmodified lines | |||
| 136 | #define RPC_TASK_NOINTR 0x0400 /* uninterruptible task */ | 135 | #define RPC_TASK_NOINTR 0x0400 /* uninterruptible task */ |
| 137 | 136 | ||
| 138 | #define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC) | 137 | #define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC) |
| 139 | #define RPC_IS_CHILD(t) ((t)->tk_flags & RPC_TASK_CHILD) | ||
| 140 | #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) | 138 | #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) |
| 141 | #define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS) | 139 | #define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS) |
| 142 | #define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED) | 140 | #define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED) |
| @@ -253,7 +251,6 @@ struct rpc_task *rpc_new_task(struct rpc_clnt *, int flags, · 110 unmodified lines | |||
| 253 | const struct rpc_call_ops *ops, void *data); | 251 | const struct rpc_call_ops *ops, void *data); |
| 254 | struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags, | 252 | struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags, |
| 255 | const struct rpc_call_ops *ops, void *data); | 253 | const struct rpc_call_ops *ops, void *data); |
| 256 | struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent); | ||
| 257 | void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, | 254 | void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, |
| 258 | int flags, const struct rpc_call_ops *ops, | 255 | int flags, const struct rpc_call_ops *ops, |
| 259 | void *data); | 256 | void *data); |
| @@ -261,8 +258,6 @@ void rpc_release_task(struct rpc_task *); · 1 unmodified line | |||
| 261 | void rpc_exit_task(struct rpc_task *); | 258 | void rpc_exit_task(struct rpc_task *); |
| 262 | void rpc_killall_tasks(struct rpc_clnt *); | 259 | void rpc_killall_tasks(struct rpc_clnt *); |
| 263 | int rpc_execute(struct rpc_task *); | 260 | int rpc_execute(struct rpc_task *); |
| 264 | void rpc_run_child(struct rpc_task *parent, struct rpc_task *child, | ||
| 265 | rpc_action action); | ||
| 266 | void rpc_init_priority_wait_queue(struct rpc_wait_queue *, const char *); | 261 | void rpc_init_priority_wait_queue(struct rpc_wait_queue *, const char *); |
| 267 | void rpc_init_wait_queue(struct rpc_wait_queue *, const char *); | 262 | void rpc_init_wait_queue(struct rpc_wait_queue *, const char *); |
| 268 | void rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *, | 263 | void rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *, |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | #include <linux/uio.h> | 12 | #include <linux/uio.h> |
| 13 | #include <linux/socket.h> | 13 | #include <linux/socket.h> |
| 14 | #include <linux/in.h> | 14 | #include <linux/in.h> |
| 15 | #include <linux/kref.h> | ||
| 15 | #include <linux/sunrpc/sched.h> | 16 | #include <linux/sunrpc/sched.h> |
| 16 | #include <linux/sunrpc/xdr.h> | 17 | #include <linux/sunrpc/xdr.h> |
| 17 | 18 | ||
| @@ -51,6 +52,14 @@ struct rpc_timeout { · 33 unmodified lines | |||
| 51 | unsigned char to_exponential; | 52 | unsigned char to_exponential; |
| 52 | }; | 53 | }; |
| 53 | 54 | ||
| 55 | enum rpc_display_format_t { | ||
| 56 | RPC_DISPLAY_ADDR = 0, | ||
| 57 | RPC_DISPLAY_PORT, | ||
| 58 | RPC_DISPLAY_PROTO, | ||
| 59 | RPC_DISPLAY_ALL, | ||
| 60 | RPC_DISPLAY_MAX, | ||
| 61 | }; | ||
| 62 | |||
| 54 | struct rpc_task; | 63 | struct rpc_task; |
| 55 | struct rpc_xprt; | 64 | struct rpc_xprt; |
| 56 | struct seq_file; | 65 | struct seq_file; |
| @@ -103,8 +112,10 @@ struct rpc_rqst { · 46 unmodified lines | |||
| 103 | 112 | ||
| 104 | struct rpc_xprt_ops { | 113 | struct rpc_xprt_ops { |
| 105 | void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize); | 114 | void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize); |
| 115 | char * (*print_addr)(struct rpc_xprt *xprt, enum rpc_display_format_t format); | ||
| 106 | int (*reserve_xprt)(struct rpc_task *task); | 116 | int (*reserve_xprt)(struct rpc_task *task); |
| 107 | void (*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); | 117 | void (*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); |
| 118 | void (*rpcbind)(struct rpc_task *task); | ||
| 108 | void (*set_port)(struct rpc_xprt *xprt, unsigned short port); | 119 | void (*set_port)(struct rpc_xprt *xprt, unsigned short port); |
| 109 | void (*connect)(struct rpc_task *task); | 120 | void (*connect)(struct rpc_task *task); |
| 110 | void * (*buf_alloc)(struct rpc_task *task, size_t size); | 121 | void * (*buf_alloc)(struct rpc_task *task, size_t size); |
| @@ -119,12 +130,14 @@ struct rpc_xprt_ops { · 8 unmodified lines | |||
| 119 | }; | 130 | }; |
| 120 | 131 | ||
| 121 | struct rpc_xprt { | 132 | struct rpc_xprt { |
| 133 | struct kref kref; /* Reference count */ | ||
| 122 | struct rpc_xprt_ops * ops; /* transport methods */ | 134 | struct rpc_xprt_ops * ops; /* transport methods */ |
| 123 | struct socket * sock; /* BSD socket layer */ | 135 | struct socket * sock; /* BSD socket layer */ |
| 124 | struct sock * inet; /* INET layer */ | 136 | struct sock * inet; /* INET layer */ |
| 125 | 137 | ||
| 126 | struct rpc_timeout timeout; /* timeout parms */ | 138 | struct rpc_timeout timeout; /* timeout parms */ |
| 127 | struct sockaddr_in addr; /* server address */ | 139 | struct sockaddr_storage addr; /* server address */ |
| 140 | size_t addrlen; /* size of server address */ | ||
| 128 | int prot; /* IP protocol */ | 141 | int prot; /* IP protocol */ |
| 129 | 142 | ||
| 130 | unsigned long cong; /* current congestion */ | 143 | unsigned long cong; /* current congestion */ |
| @@ -138,6 +151,7 @@ struct rpc_xprt { · 7 unmodified lines | |||
| 138 | unsigned int tsh_size; /* size of transport specific | 151 | unsigned int tsh_size; /* size of transport specific |
| 139 | header */ | 152 | header */ |
| 140 | 153 | ||
| 154 | struct rpc_wait_queue binding; /* requests waiting on rpcbind */ | ||
| 141 | struct rpc_wait_queue sending; /* requests waiting to send */ | 155 | struct rpc_wait_queue sending; /* requests waiting to send */ |
| 142 | struct rpc_wait_queue resend; /* requests waiting to resend */ | 156 | struct rpc_wait_queue resend; /* requests waiting to resend */ |
| 143 | struct rpc_wait_queue pending; /* requests in flight */ | 157 | struct rpc_wait_queue pending; /* requests in flight */ |
| @@ -205,6 +219,8 @@ struct rpc_xprt { · 61 unmodified lines | |||
| 205 | void (*old_data_ready)(struct sock *, int); | 219 | void (*old_data_ready)(struct sock *, int); |
| 206 | void (*old_state_change)(struct sock *); | 220 | void (*old_state_change)(struct sock *); |
| 207 | void (*old_write_space)(struct sock *); | 221 | void (*old_write_space)(struct sock *); |
| 222 | |||
| 223 | char * address_strings[RPC_DISPLAY_MAX]; | ||
| 208 | }; | 224 | }; |
| 209 | 225 | ||
| 210 | #define XPRT_LAST_FRAG (1 << 0) | 226 | #define XPRT_LAST_FRAG (1 << 0) |
| @@ -217,12 +233,12 @@ struct rpc_xprt { · 6 unmodified lines | |||
| 217 | /* | 233 | /* |
| 218 | * Transport operations used by ULPs | 234 | * Transport operations used by ULPs |
| 219 | */ | 235 | */ |
| 220 | struct rpc_xprt * xprt_create_proto(int proto, struct sockaddr_in *addr, struct rpc_timeout *to); | ||
| 221 | void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr); | 236 | void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr); |
| 222 | 237 | ||
| 223 | /* | 238 | /* |
| 224 | * Generic internal transport functions | 239 | * Generic internal transport functions |
| 225 | */ | 240 | */ |
| 241 | struct rpc_xprt * xprt_create_transport(int proto, struct sockaddr *addr, size_t size, struct rpc_timeout *toparms); | ||
| 226 | void xprt_connect(struct rpc_task *task); | 242 | void xprt_connect(struct rpc_task *task); |
| 227 | void xprt_reserve(struct rpc_task *task); | 243 | void xprt_reserve(struct rpc_task *task); |
| 228 | int xprt_reserve_xprt(struct rpc_task *task); | 244 | int xprt_reserve_xprt(struct rpc_task *task); |
| @@ -234,7 +250,8 @@ int xprt_adjust_timeout(struct rpc_rqst *req); · 5 unmodified lines | |||
| 234 | void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task); | 250 | void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task); |
| 235 | void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); | 251 | void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); |
| 236 | void xprt_release(struct rpc_task *task); | 252 | void xprt_release(struct rpc_task *task); |
| 237 | int xprt_destroy(struct rpc_xprt *xprt); | 253 | struct rpc_xprt * xprt_get(struct rpc_xprt *xprt); |
| 254 | void xprt_put(struct rpc_xprt *xprt); | ||
| 238 | 255 | ||
| 239 | static inline u32 *xprt_skip_transport_header(struct rpc_xprt *xprt, u32 *p) | 256 | static inline u32 *xprt_skip_transport_header(struct rpc_xprt *xprt, u32 *p) |
| 240 | { | 257 | { |
| @@ -269,6 +286,8 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to); · 28 unmodified lines | |||
| 269 | #define XPRT_CONNECTED (1) | 286 | #define XPRT_CONNECTED (1) |
| 270 | #define XPRT_CONNECTING (2) | 287 | #define XPRT_CONNECTING (2) |
| 271 | #define XPRT_CLOSE_WAIT (3) | 288 | #define XPRT_CLOSE_WAIT (3) |
| 289 | #define XPRT_BOUND (4) | ||
| 290 | #define XPRT_BINDING (5) | ||
| 272 | 291 | ||
| 273 | static inline void xprt_set_connected(struct rpc_xprt *xprt) | 292 | static inline void xprt_set_connected(struct rpc_xprt *xprt) |
| 274 | { | 293 | { |
| @@ -312,6 +331,33 @@ static inline int xprt_test_and_set_connecting(struct rpc_xprt *xprt) · 37 unmodified lines | |||
| 312 | return test_and_set_bit(XPRT_CONNECTING, &xprt->state); | 331 | return test_and_set_bit(XPRT_CONNECTING, &xprt->state); |
| 313 | } | 332 | } |
| 314 | 333 | ||
| 334 | static inline void xprt_set_bound(struct rpc_xprt *xprt) | ||
| 335 | { | ||
| 336 | test_and_set_bit(XPRT_BOUND, &xprt->state); | ||
| 337 | } | ||
| 338 | |||
| 339 | static inline int xprt_bound(struct rpc_xprt *xprt) | ||
| 340 | { | ||
| 341 | return test_bit(XPRT_BOUND, &xprt->state); | ||
| 342 | } | ||
| 343 | |||
| 344 | static inline void xprt_clear_bound(struct rpc_xprt *xprt) | ||
| 345 | { | ||
| 346 | clear_bit(XPRT_BOUND, &xprt->state); | ||
| 347 | } | ||
| 348 | |||
| 349 | static inline void xprt_clear_binding(struct rpc_xprt *xprt) | ||
| 350 | { | ||
| 351 | smp_mb__before_clear_bit(); | ||
| 352 | clear_bit(XPRT_BINDING, &xprt->state); | ||
| 353 | smp_mb__after_clear_bit(); | ||
| 354 | } | ||
| 355 | |||
| 356 | static inline int xprt_test_and_set_binding(struct rpc_xprt *xprt) | ||
| 357 | { | ||
| 358 | return test_and_set_bit(XPRT_BINDING, &xprt->state); | ||
| 359 | } | ||
| 360 | |||
| 315 | #endif /* __KERNEL__*/ | 361 | #endif /* __KERNEL__*/ |
| 316 | 362 | ||
| 317 | #endif /* _LINUX_SUNRPC_XPRT_H */ | 363 | #endif /* _LINUX_SUNRPC_XPRT_H */ |
| @@ -411,6 +411,10 @@ enum · 410 unmodified lines | |||
| 411 | NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS=115, | 411 | NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS=115, |
| 412 | NET_TCP_DMA_COPYBREAK=116, | 412 | NET_TCP_DMA_COPYBREAK=116, |
| 413 | NET_TCP_SLOW_START_AFTER_IDLE=117, | 413 | NET_TCP_SLOW_START_AFTER_IDLE=117, |
| 414 | NET_CIPSOV4_CACHE_ENABLE=118, | ||
| 415 | NET_CIPSOV4_CACHE_BUCKET_SIZE=119, | ||
| 416 | NET_CIPSOV4_RBM_OPTFMT=120, | ||
| 417 | NET_CIPSOV4_RBM_STRICTVALID=121, | ||
| 414 | }; | 418 | }; |
| 415 | 419 | ||
| 416 | enum { | 420 | enum { |
| @@ -552,6 +556,7 @@ enum { · 135 unmodified lines | |||
| 552 | NET_IPV6_ACCEPT_RA_RTR_PREF=20, | 556 | NET_IPV6_ACCEPT_RA_RTR_PREF=20, |
| 553 | NET_IPV6_RTR_PROBE_INTERVAL=21, | 557 | NET_IPV6_RTR_PROBE_INTERVAL=21, |
| 554 | NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, | 558 | NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, |
| 559 | NET_IPV6_PROXY_NDP=23, | ||
| 555 | __NET_IPV6_MAX | 560 | __NET_IPV6_MAX |
| 556 | }; | 561 | }; |
| 557 | 562 | ||
| @@ -85,6 +85,7 @@ int wakeup_pdflush(long nr_pages); · 84 unmodified lines | |||
| 85 | void laptop_io_completion(void); | 85 | void laptop_io_completion(void); |
| 86 | void laptop_sync_completion(void); | 86 | void laptop_sync_completion(void); |
| 87 | void throttle_vm_writeout(void); | 87 | void throttle_vm_writeout(void); |
| 88 | void writeback_congestion_end(void); | ||
| 88 | 89 | ||
| 89 | /* These are exported to sysctl. */ | 90 | /* These are exported to sysctl. */ |
| 90 | extern int dirty_background_ratio; | 91 | extern int dirty_background_ratio; |
| @@ -102,6 +102,13 @@ struct xfrm_stats { · 101 unmodified lines | |||
| 102 | __u32 integrity_failed; | 102 | __u32 integrity_failed; |
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | enum | ||
| 106 | { | ||
| 107 | XFRM_POLICY_TYPE_MAIN = 0, | ||
| 108 | XFRM_POLICY_TYPE_SUB = 1, | ||
| 109 | XFRM_POLICY_TYPE_MAX = 2 | ||
| 110 | }; | ||
| 111 | |||
| 105 | enum | 112 | enum |
| 106 | { | 113 | { |
| 107 | XFRM_POLICY_IN = 0, | 114 | XFRM_POLICY_IN = 0, |
| @@ -120,7 +127,9 @@ enum · 12 unmodified lines | |||
| 120 | 127 | ||
| 121 | #define XFRM_MODE_TRANSPORT 0 | 128 | #define XFRM_MODE_TRANSPORT 0 |
| 122 | #define XFRM_MODE_TUNNEL 1 | 129 | #define XFRM_MODE_TUNNEL 1 |
| 123 | #define XFRM_MODE_MAX 2 | 130 | #define XFRM_MODE_ROUTEOPTIMIZATION 2 |
| 131 | #define XFRM_MODE_IN_TRIGGER 3 | ||
| 132 | #define XFRM_MODE_MAX 4 | ||
| 124 | 133 | ||
| 125 | /* Netlink configuration messages. */ | 134 | /* Netlink configuration messages. */ |
| 126 | enum { | 135 | enum { |
| @@ -164,6 +173,10 @@ enum { · 37 unmodified lines | |||
| 164 | #define XFRM_MSG_NEWAE XFRM_MSG_NEWAE | 173 | #define XFRM_MSG_NEWAE XFRM_MSG_NEWAE |
| 165 | XFRM_MSG_GETAE, | 174 | XFRM_MSG_GETAE, |
| 166 | #define XFRM_MSG_GETAE XFRM_MSG_GETAE | 175 | #define XFRM_MSG_GETAE XFRM_MSG_GETAE |
| 176 | |||
| 177 | XFRM_MSG_REPORT, | ||
| 178 | #define XFRM_MSG_REPORT XFRM_MSG_REPORT | ||
| 179 | |||
| 167 | __XFRM_MSG_MAX | 180 | __XFRM_MSG_MAX |
| 168 | }; | 181 | }; |
| 169 | #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) | 182 | #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) |
| @@ -217,6 +230,12 @@ enum xfrm_ae_ftype_t { · 47 unmodified lines | |||
| 217 | #define XFRM_AE_MAX (__XFRM_AE_MAX - 1) | 230 | #define XFRM_AE_MAX (__XFRM_AE_MAX - 1) |
| 218 | }; | 231 | }; |
| 219 | 232 | ||
| 233 | struct xfrm_userpolicy_type { | ||
| 234 | __u8 type; | ||
| 235 | __u16 reserved1; | ||
| 236 | __u8 reserved2; | ||
| 237 | }; | ||
| 238 | |||
| 220 | /* Netlink message attributes. */ | 239 | /* Netlink message attributes. */ |
| 221 | enum xfrm_attr_type_t { | 240 | enum xfrm_attr_type_t { |
| 222 | XFRMA_UNSPEC, | 241 | XFRMA_UNSPEC, |
| @@ -232,6 +251,10 @@ enum xfrm_attr_type_t { · 9 unmodified lines | |||
| 232 | XFRMA_REPLAY_VAL, | 251 | XFRMA_REPLAY_VAL, |
| 233 | XFRMA_REPLAY_THRESH, | 252 | XFRMA_REPLAY_THRESH, |
| 234 | XFRMA_ETIMER_THRESH, | 253 | XFRMA_ETIMER_THRESH, |
| 254 | XFRMA_SRCADDR, /* xfrm_address_t */ | ||
| 255 | XFRMA_COADDR, /* xfrm_address_t */ | ||
| 256 | XFRMA_LASTUSED, | ||
| 257 | XFRMA_POLICY_TYPE, /* struct xfrm_userpolicy_type */ | ||
| 235 | __XFRMA_MAX | 258 | __XFRMA_MAX |
| 236 | 259 | ||
| 237 | #define XFRMA_MAX (__XFRMA_MAX - 1) | 260 | #define XFRMA_MAX (__XFRMA_MAX - 1) |
| @@ -247,12 +270,13 @@ struct xfrm_usersa_info { · 9 unmodified lines | |||
| 247 | __u32 seq; | 270 | __u32 seq; |
| 248 | __u32 reqid; | 271 | __u32 reqid; |
| 249 | __u16 family; | 272 | __u16 family; |
| 250 | __u8 mode; /* 0=transport,1=tunnel */ | 273 | __u8 mode; /* XFRM_MODE_xxx */ |
| 251 | __u8 replay_window; | 274 | __u8 replay_window; |
| 252 | __u8 flags; | 275 | __u8 flags; |
| 253 | #define XFRM_STATE_NOECN 1 | 276 | #define XFRM_STATE_NOECN 1 |
| 254 | #define XFRM_STATE_DECAP_DSCP 2 | 277 | #define XFRM_STATE_DECAP_DSCP 2 |
| 255 | #define XFRM_STATE_NOPMTUDISC 4 | 278 | #define XFRM_STATE_NOPMTUDISC 4 |
| 279 | #define XFRM_STATE_WILDRECV 8 | ||
| 256 | }; | 280 | }; |
| 257 | 281 | ||
| 258 | struct xfrm_usersa_id { | 282 | struct xfrm_usersa_id { |
| @@ -319,12 +343,18 @@ struct xfrm_usersa_flush { · 60 unmodified lines | |||
| 319 | __u8 proto; | 343 | __u8 proto; |
| 320 | }; | 344 | }; |
| 321 | 345 | ||
| 346 | struct xfrm_user_report { | ||
| 347 | __u8 proto; | ||
| 348 | struct xfrm_selector sel; | ||
| 349 | }; | ||
| 350 | |||
| 322 | #ifndef __KERNEL__ | 351 | #ifndef __KERNEL__ |
| 323 | /* backwards compatibility for userspace */ | 352 | /* backwards compatibility for userspace */ |
| 324 | #define XFRMGRP_ACQUIRE 1 | 353 | #define XFRMGRP_ACQUIRE 1 |
| 325 | #define XFRMGRP_EXPIRE 2 | 354 | #define XFRMGRP_EXPIRE 2 |
| 326 | #define XFRMGRP_SA 4 | 355 | #define XFRMGRP_SA 4 |
| 327 | #define XFRMGRP_POLICY 8 | 356 | #define XFRMGRP_POLICY 8 |
| 357 | #define XFRMGRP_REPORT 0x10 | ||
| 328 | #endif | 358 | #endif |
| 329 | 359 | ||
| 330 | enum xfrm_nlgroups { | 360 | enum xfrm_nlgroups { |
| @@ -340,6 +370,8 @@ enum xfrm_nlgroups { · 9 unmodified lines | |||
| 340 | #define XFRMNLGRP_POLICY XFRMNLGRP_POLICY | 370 | #define XFRMNLGRP_POLICY XFRMNLGRP_POLICY |
| 341 | XFRMNLGRP_AEVENTS, | 371 | XFRMNLGRP_AEVENTS, |
| 342 | #define XFRMNLGRP_AEVENTS XFRMNLGRP_AEVENTS | 372 | #define XFRMNLGRP_AEVENTS XFRMNLGRP_AEVENTS |
| 373 | XFRMNLGRP_REPORT, | ||
| 374 | #define XFRMNLGRP_REPORT XFRMNLGRP_REPORT | ||
| 343 | __XFRMNLGRP_MAX | 375 | __XFRMNLGRP_MAX |
| 344 | }; | 376 | }; |
| 345 | #define XFRMNLGRP_MAX (__XFRMNLGRP_MAX - 1) | 377 | #define XFRMNLGRP_MAX (__XFRMNLGRP_MAX - 1) |
| @@ -8,70 +8,110 @@ · 7 unmodified lines | |||
| 8 | #include <net/sch_generic.h> | 8 | #include <net/sch_generic.h> |
| 9 | #include <net/pkt_sched.h> | 9 | #include <net/pkt_sched.h> |
| 10 | 10 | ||
| 11 | #define tca_gen(name) \ | 11 | struct tcf_common { |
| 12 | struct tcf_##name *next; \ | 12 | struct tcf_common *tcfc_next; |
| 13 | u32 index; \ | 13 | u32 tcfc_index; |
| 14 | int refcnt; \ | 14 | int tcfc_refcnt; |
| 15 | int bindcnt; \ | 15 | int tcfc_bindcnt; |
| 16 | u32 capab; \ | 16 | u32 tcfc_capab; |
| 17 | int action; \ | 17 | int tcfc_action; |
| 18 | struct tcf_t tm; \ | 18 | struct tcf_t tcfc_tm; |
| 19 | struct gnet_stats_basic bstats; \ | 19 | struct gnet_stats_basic tcfc_bstats; |
| 20 | struct gnet_stats_queue qstats; \ | 20 | struct gnet_stats_queue tcfc_qstats; |
| 21 | struct gnet_stats_rate_est rate_est; \ | 21 | struct gnet_stats_rate_est tcfc_rate_est; |
| 22 | spinlock_t *stats_lock; \ | 22 | spinlock_t *tcfc_stats_lock; |
| 23 | spinlock_t lock | 23 | spinlock_t tcfc_lock; |
| 24 | 24 | }; | |
| 25 | struct tcf_police | 25 | #define tcf_next common.tcfc_next |
| 26 | { | 26 | #define tcf_index common.tcfc_index |
| 27 | tca_gen(police); | 27 | #define tcf_refcnt common.tcfc_refcnt |
| 28 | int result; | 28 | #define tcf_bindcnt common.tcfc_bindcnt |
| 29 | u32 ewma_rate; | 29 | #define tcf_capab common.tcfc_capab |
| 30 | u32 burst; | 30 | #define tcf_action common.tcfc_action |
| 31 | u32 mtu; | 31 | #define tcf_tm common.tcfc_tm |
| 32 | u32 toks; | 32 | #define tcf_bstats common.tcfc_bstats |
| 33 | u32 ptoks; | 33 | #define tcf_qstats common.tcfc_qstats |
| 34 | psched_time_t t_c; | 34 | #define tcf_rate_est common.tcfc_rate_est |
| 35 | struct qdisc_rate_table *R_tab; | 35 | #define tcf_stats_lock common.tcfc_stats_lock |
| 36 | struct qdisc_rate_table *P_tab; | 36 | #define tcf_lock common.tcfc_lock |
| 37 | |||
| 38 | struct tcf_police { | ||
| 39 | struct tcf_common common; | ||
| 40 | int tcfp_result; | ||
| 41 | u32 tcfp_ewma_rate; | ||
| 42 | u32 tcfp_burst; | ||
| 43 | u32 tcfp_mtu; | ||
| 44 | u32 tcfp_toks; | ||
| 45 | u32 tcfp_ptoks; | ||
| 46 | psched_time_t tcfp_t_c; | ||
| 47 | struct qdisc_rate_table *tcfp_R_tab; | ||
| 48 | struct qdisc_rate_table *tcfp_P_tab; | ||
| 37 | }; | 49 | }; |
| 50 | #define to_police(pc) \ | ||
| 51 | container_of(pc, struct tcf_police, common) | ||
| 52 | |||
| 53 | struct tcf_hashinfo { | ||
| 54 | struct tcf_common **htab; | ||
| 55 | unsigned int hmask; | ||
| 56 | rwlock_t *lock; | ||
| 57 | }; | ||
| 58 | |||
| 59 | static inline unsigned int tcf_hash(u32 index, unsigned int hmask) | ||
| 60 | { | ||
| 61 | return index & hmask; | ||
| 62 | } | ||
| 38 | 63 | ||
| 39 | #ifdef CONFIG_NET_CLS_ACT | 64 | #ifdef CONFIG_NET_CLS_ACT |
| 40 | 65 | ||
| 41 | #define ACT_P_CREATED 1 | 66 | #define ACT_P_CREATED 1 |
| 42 | #define ACT_P_DELETED 1 | 67 | #define ACT_P_DELETED 1 |
| 43 | 68 | ||
| 44 | struct tcf_act_hdr | 69 | struct tcf_act_hdr { |
| 45 | { | 70 | struct tcf_common common; |
| 46 | tca_gen(act_hdr); | ||
| 47 | }; | 71 | }; |
| 48 | 72 | ||
| 49 | struct tc_action | 73 | struct tc_action { |
| 50 | { | 74 | void *priv; |
| 51 | void *priv; | 75 | struct tc_action_ops *ops; |
| 52 | struct tc_action_ops *ops; | 76 | __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ |
| 53 | __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ | 77 | __u32 order; |
| 54 | __u32 order; | 78 | struct tc_action *next; |
| 55 | struct tc_action *next; | ||
| 56 | }; | 79 | }; |
| 57 | 80 | ||
| 58 | #define TCA_CAP_NONE 0 | 81 | #define TCA_CAP_NONE 0 |
| 59 | struct tc_action_ops | 82 | struct tc_action_ops { |
| 60 | { | ||
| 61 | struct tc_action_ops *next; | 83 | struct tc_action_ops *next; |
| 84 | struct tcf_hashinfo *hinfo; | ||
| 62 | char kind[IFNAMSIZ]; | 85 | char kind[IFNAMSIZ]; |
| 63 | __u32 type; /* TBD to match kind */ | 86 | __u32 type; /* TBD to match kind */ |
| 64 | __u32 capab; /* capabilities includes 4 bit version */ | 87 | __u32 capab; /* capabilities includes 4 bit version */ |
| 65 | struct module *owner; | 88 | struct module *owner; |
| 66 | int (*act)(struct sk_buff *, struct tc_action *, struct tcf_result *); | 89 | int (*act)(struct sk_buff *, struct tc_action *, struct tcf_result *); |
| 67 | int (*get_stats)(struct sk_buff *, struct tc_action *); | 90 | int (*get_stats)(struct sk_buff *, struct tc_action *); |
| 68 | int (*dump)(struct sk_buff *, struct tc_action *,int , int); | 91 | int (*dump)(struct sk_buff *, struct tc_action *, int, int); |
| 69 | int (*cleanup)(struct tc_action *, int bind); | 92 | int (*cleanup)(struct tc_action *, int bind); |
| 70 | int (*lookup)(struct tc_action *, u32 ); | 93 | int (*lookup)(struct tc_action *, u32); |
| 71 | int (*init)(struct rtattr *,struct rtattr *,struct tc_action *, int , int ); | 94 | int (*init)(struct rtattr *, struct rtattr *, struct tc_action *, int , int); |
| 72 | int (*walk)(struct sk_buff *, struct netlink_callback *, int , struct tc_action *); | 95 | int (*walk)(struct sk_buff *, struct netlink_callback *, int, struct tc_action *); |
| 73 | }; | 96 | }; |
| 74 | 97 | ||
| 98 | extern struct tcf_common *tcf_hash_lookup(u32 index, | ||
| 99 | struct tcf_hashinfo *hinfo); | ||
| 100 | extern void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo); | ||
| 101 | extern int tcf_hash_release(struct tcf_common *p, int bind, | ||
| 102 | struct tcf_hashinfo *hinfo); | ||
| 103 | extern int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, | ||
| 104 | int type, struct tc_action *a); | ||
| 105 | extern u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo); | ||
| 106 | extern int tcf_hash_search(struct tc_action *a, u32 index); | ||
| 107 | extern struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, | ||
| 108 | int bind, struct tcf_hashinfo *hinfo); | ||
| 109 | extern struct tcf_common *tcf_hash_create(u32 index, struct rtattr *est, | ||
| 110 | struct tc_action *a, int size, | ||
| 111 | int bind, u32 *idx_gen, | ||
| 112 | struct tcf_hashinfo *hinfo); | ||
| 113 | extern void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo); | ||
| 114 | |||
| 75 | extern int tcf_register_action(struct tc_action_ops *a); | 115 | extern int tcf_register_action(struct tc_action_ops *a); |
| 76 | extern int tcf_unregister_action(struct tc_action_ops *a); | 116 | extern int tcf_unregister_action(struct tc_action_ops *a); |
| 77 | extern void tcf_action_destroy(struct tc_action *a, int bind); | 117 | extern void tcf_action_destroy(struct tc_action *a, int bind); |
| @@ -96,17 +136,17 @@ tcf_police_release(struct tcf_police *p, int bind) · 18 unmodified lines | |||
| 96 | int ret = 0; | 136 | int ret = 0; |
| 97 | #ifdef CONFIG_NET_CLS_ACT | 137 | #ifdef CONFIG_NET_CLS_ACT |
| 98 | if (p) { | 138 | if (p) { |
| 99 | if (bind) { | 139 | if (bind) |
| 100 | p->bindcnt--; | 140 | p->tcf_bindcnt--; |
| 101 | } | 141 | |
| 102 | p->refcnt--; | 142 | p->tcf_refcnt--; |
| 103 | if (p->refcnt <= 0 && !p->bindcnt) { | 143 | if (p->tcf_refcnt <= 0 && !p->tcf_bindcnt) { |
| 104 | tcf_police_destroy(p); | 144 | tcf_police_destroy(p); |
| 105 | ret = 1; | 145 | ret = 1; |
| 106 | } | 146 | } |
| 107 | } | 147 | } |
| 108 | #else | 148 | #else |
| 109 | if (p && --p->refcnt == 0) | 149 | if (p && --p->tcf_refcnt == 0) |
| 110 | tcf_police_destroy(p); | 150 | tcf_police_destroy(p); |
| 111 | 151 | ||
| 112 | #endif /* CONFIG_NET_CLS_ACT */ | 152 | #endif /* CONFIG_NET_CLS_ACT */ |
| @@ -1,142 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * include/net/act_generic.h | ||
| 3 | * | ||
| 4 | */ | ||
| 5 | #ifndef _NET_ACT_GENERIC_H | ||
| 6 | #define _NET_ACT_GENERIC_H | ||
| 7 | static inline int tcf_defact_release(struct tcf_defact *p, int bind) | ||
| 8 | { | ||
| 9 | int ret = 0; | ||
| 10 | if (p) { | ||
| 11 | if (bind) { | ||
| 12 | p->bindcnt--; | ||
| 13 | } | ||
| 14 | p->refcnt--; | ||
| 15 | if (p->bindcnt <= 0 && p->refcnt <= 0) { | ||
| 16 | kfree(p->defdata); | ||
| 17 | tcf_hash_destroy(p); | ||
| 18 | ret = 1; | ||
| 19 | } | ||
| 20 | } | ||
| 21 | return ret; | ||
| 22 | } | ||
| 23 | |||
| 24 | static inline int | ||
| 25 | alloc_defdata(struct tcf_defact *p, u32 datalen, void *defdata) | ||
| 26 | { | ||
| 27 | p->defdata = kmalloc(datalen, GFP_KERNEL); | ||
| 28 | if (p->defdata == NULL) | ||
| 29 | return -ENOMEM; | ||
| 30 | p->datalen = datalen; | ||
| 31 | memcpy(p->defdata, defdata, datalen); | ||
| 32 | return 0; | ||
| 33 | } | ||
| 34 | |||
| 35 | static inline int | ||
| 36 | realloc_defdata(struct tcf_defact *p, u32 datalen, void *defdata) | ||
| 37 | { | ||
| 38 | /* safer to be just brute force for now */ | ||
| 39 | kfree(p->defdata); | ||
| 40 | return alloc_defdata(p, datalen, defdata); | ||
| 41 | } | ||
| 42 | |||
| 43 | static inline int | ||
| 44 | tcf_defact_init(struct rtattr *rta, struct rtattr *est, | ||
| 45 | struct tc_action *a, int ovr, int bind) | ||
| 46 | { | ||
| 47 | struct rtattr *tb[TCA_DEF_MAX]; | ||
| 48 | struct tc_defact *parm; | ||
| 49 | struct tcf_defact *p; | ||
| 50 | void *defdata; | ||
| 51 | u32 datalen = 0; | ||
| 52 | int ret = 0; | ||
| 53 | |||
| 54 | if (rta == NULL || rtattr_parse_nested(tb, TCA_DEF_MAX, rta) < 0) | ||
| 55 | return -EINVAL; | ||
| 56 | |||
| 57 | if (tb[TCA_DEF_PARMS - 1] == NULL || | ||
| 58 | RTA_PAYLOAD(tb[TCA_DEF_PARMS - 1]) < sizeof(*parm)) | ||
| 59 | return -EINVAL; | ||
| 60 | |||
| 61 | parm = RTA_DATA(tb[TCA_DEF_PARMS - 1]); | ||
| 62 | defdata = RTA_DATA(tb[TCA_DEF_DATA - 1]); | ||
| 63 | if (defdata == NULL) | ||
| 64 | return -EINVAL; | ||
| 65 | |||
| 66 | datalen = RTA_PAYLOAD(tb[TCA_DEF_DATA - 1]); | ||
| 67 | if (datalen <= 0) | ||
| 68 | return -EINVAL; | ||
| 69 | |||
| 70 | p = tcf_hash_check(parm->index, a, ovr, bind); | ||
| 71 | if (p == NULL) { | ||
| 72 | p = tcf_hash_create(parm->index, est, a, sizeof(*p), ovr, bind); | ||
| 73 | if (p == NULL) | ||
| 74 | return -ENOMEM; | ||
| 75 | |||
| 76 | ret = alloc_defdata(p, datalen, defdata); | ||
| 77 | if (ret < 0) { | ||
| 78 | kfree(p); | ||
| 79 | return ret; | ||
| 80 | } | ||
| 81 | ret = ACT_P_CREATED; | ||
| 82 | } else { | ||
| 83 | if (!ovr) { | ||
| 84 | tcf_defact_release(p, bind); | ||
| 85 | return -EEXIST; | ||
| 86 | } | ||
| 87 | realloc_defdata(p, datalen, defdata); | ||
| 88 | } | ||
| 89 | |||
| 90 | spin_lock_bh(&p->lock); | ||
| 91 | p->action = parm->action; | ||
| 92 | spin_unlock_bh(&p->lock); | ||
| 93 | if (ret == ACT_P_CREATED) | ||
| 94 | tcf_hash_insert(p); | ||
| 95 | return ret; | ||
| 96 | } | ||
| 97 | |||
| 98 | static inline int tcf_defact_cleanup(struct tc_action *a, int bind) | ||
| 99 | { | ||
| 100 | struct tcf_defact *p = PRIV(a, defact); | ||
| 101 | |||
| 102 | if (p != NULL) | ||
| 103 | return tcf_defact_release(p, bind); | ||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | static inline int | ||
| 108 | tcf_defact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | ||
| 109 | { | ||
| 110 | unsigned char *b = skb->tail; | ||
| 111 | struct tc_defact opt; | ||
| 112 | struct tcf_defact *p = PRIV(a, defact); | ||
| 113 | struct tcf_t t; | ||
| 114 | |||
| 115 | opt.index = p->index; | ||
| 116 | opt.refcnt = p->refcnt - ref; | ||
| 117 | opt.bindcnt = p->bindcnt - bind; | ||
| 118 | opt.action = p->action; | ||
| 119 | RTA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt); | ||
| 120 | RTA_PUT(skb, TCA_DEF_DATA, p->datalen, p->defdata); | ||
| 121 | t.install = jiffies_to_clock_t(jiffies - p->tm.install); | ||
| 122 | t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse); | ||
| 123 | t.expires = jiffies_to_clock_t(p->tm.expires); | ||
| 124 | RTA_PUT(skb, TCA_DEF_TM, sizeof(t), &t); | ||
| 125 | return skb->len; | ||
| 126 | |||
| 127 | rtattr_failure: | ||
| 128 | skb_trim(skb, b - skb->data); | ||
| 129 | return -1; | ||
| 130 | } | ||
| 131 | |||
| 132 | #define tca_use_default_ops \ | ||
| 133 | .dump = tcf_defact_dump, \ | ||
| 134 | .cleanup = tcf_defact_cleanup, \ | ||
| 135 | .init = tcf_defact_init, \ | ||
| 136 | .walk = tcf_generic_walker, \ | ||
| 137 | |||
| 138 | #define tca_use_default_defines(name) \ | ||
| 139 | static u32 idx_gen; \ | ||
| 140 | static struct tcf_defact *tcf_##name_ht[MY_TAB_SIZE]; \ | ||
| 141 | static DEFINE_RWLOCK(##name_lock); | ||
| 142 | #endif /* _NET_ACT_GENERIC_H */ | ||
| @@ -61,6 +61,9 @@ extern int addrconf_set_dstaddr(void __user *arg); · 60 unmodified lines | |||
| 61 | extern int ipv6_chk_addr(struct in6_addr *addr, | 61 | extern int ipv6_chk_addr(struct in6_addr *addr, |
| 62 | struct net_device *dev, | 62 | struct net_device *dev, |
| 63 | int strict); | 63 | int strict); |
| 64 | #ifdef CONFIG_IPV6_MIP6 | ||
| 65 | extern int ipv6_chk_home_addr(struct in6_addr *addr); | ||
| 66 | #endif | ||
| 64 | extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, | 67 | extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, |
| 65 | struct net_device *dev, | 68 | struct net_device *dev, |
| 66 | int strict); | 69 | int strict); |
| @@ -126,20 +129,18 @@ extern int unregister_inet6addr_notifier(struct notifier_block *nb); · 59 unmodified lines | |||
| 126 | static inline struct inet6_dev * | 129 | static inline struct inet6_dev * |
| 127 | __in6_dev_get(struct net_device *dev) | 130 | __in6_dev_get(struct net_device *dev) |
| 128 | { | 131 | { |
| 129 | return (struct inet6_dev *)dev->ip6_ptr; | 132 | return rcu_dereference(dev->ip6_ptr); |
| 130 | } | 133 | } |
| 131 | 134 | ||
| 132 | extern rwlock_t addrconf_lock; | ||
| 133 | |||
| 134 | static inline struct inet6_dev * | 135 | static inline struct inet6_dev * |
| 135 | in6_dev_get(struct net_device *dev) | 136 | in6_dev_get(struct net_device *dev) |
| 136 | { | 137 | { |
| 137 | struct inet6_dev *idev = NULL; | 138 | struct inet6_dev *idev = NULL; |
| 138 | read_lock(&addrconf_lock); | 139 | rcu_read_lock(); |
| 139 | idev = dev->ip6_ptr; | 140 | idev = __in6_dev_get(dev); |
| 140 | if (idev) | 141 | if (idev) |
| 141 | atomic_inc(&idev->refcnt); | 142 | atomic_inc(&idev->refcnt); |
| 142 | read_unlock(&addrconf_lock); | 143 | rcu_read_unlock(); |
| 143 | return idev; | 144 | return idev; |
| 144 | } | 145 | } |
| 145 | 146 | ||
| @@ -0,0 +1,246 @@ | |||
| 1 | /* | ||
| 2 | * CIPSO - Commercial IP Security Option | ||
| 3 | * | ||
| 4 | * This is an implementation of the CIPSO 2.2 protocol as specified in | ||
| 5 | * draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in | ||
| 6 | * FIPS-188, copies of both documents can be found in the Documentation | ||
| 7 | * directory. While CIPSO never became a full IETF RFC standard many vendors | ||
| 8 | * have chosen to adopt the protocol and over the years it has become a | ||
| 9 | * de-facto standard for labeled networking. | ||
| 10 | * | ||
| 11 | * Author: Paul Moore <paul.moore@hp.com> | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | /* | ||
| 16 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 | ||
| 17 | * | ||
| 18 | * This program is free software; you can redistribute it and/or modify | ||
| 19 | * it under the terms of the GNU General Public License as published by | ||
| 20 | * the Free Software Foundation; either version 2 of the License, or | ||
| 21 | * (at your option) any later version. | ||
| 22 | * | ||
| 23 | * This program is distributed in the hope that it will be useful, | ||
| 24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
| 26 | * the GNU General Public License for more details. | ||
| 27 | * | ||
| 28 | * You should have received a copy of the GNU General Public License | ||
| 29 | * along with this program; if not, write to the Free Software | ||
| 30 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 31 | * | ||
| 32 | */ | ||
| 33 | |||
| 34 | #ifndef _CIPSO_IPV4_H | ||
| 35 | #define _CIPSO_IPV4_H | ||
| 36 | |||
| 37 | #include <linux/types.h> | ||
| 38 | #include <linux/rcupdate.h> | ||
| 39 | #include <linux/list.h> | ||
| 40 | #include <linux/net.h> | ||
| 41 | #include <linux/skbuff.h> | ||
| 42 | #include <net/netlabel.h> | ||
| 43 | |||
| 44 | /* known doi values */ | ||
| 45 | #define CIPSO_V4_DOI_UNKNOWN 0x00000000 | ||
| 46 | |||
| 47 | /* tag types */ | ||
| 48 | #define CIPSO_V4_TAG_INVALID 0 | ||
| 49 | #define CIPSO_V4_TAG_RBITMAP 1 | ||
| 50 | #define CIPSO_V4_TAG_ENUM 2 | ||
| 51 | #define CIPSO_V4_TAG_RANGE 5 | ||
| 52 | #define CIPSO_V4_TAG_PBITMAP 6 | ||
| 53 | #define CIPSO_V4_TAG_FREEFORM 7 | ||
| 54 | |||
| 55 | /* doi mapping types */ | ||
| 56 | #define CIPSO_V4_MAP_UNKNOWN 0 | ||
| 57 | #define CIPSO_V4_MAP_STD 1 | ||
| 58 | #define CIPSO_V4_MAP_PASS 2 | ||
| 59 | |||
| 60 | /* limits */ | ||
| 61 | #define CIPSO_V4_MAX_REM_LVLS 256 | ||
| 62 | #define CIPSO_V4_INV_LVL 0x80000000 | ||
| 63 | #define CIPSO_V4_MAX_LOC_LVLS (CIPSO_V4_INV_LVL - 1) | ||
| 64 | #define CIPSO_V4_MAX_REM_CATS 65536 | ||
| 65 | #define CIPSO_V4_INV_CAT 0x80000000 | ||
| 66 | #define CIPSO_V4_MAX_LOC_CATS (CIPSO_V4_INV_CAT - 1) | ||
| 67 | |||
| 68 | /* | ||
| 69 | * CIPSO DOI definitions | ||
| 70 | */ | ||
| 71 | |||
| 72 | /* DOI definition struct */ | ||
| 73 | #define CIPSO_V4_TAG_MAXCNT 5 | ||
| 74 | struct cipso_v4_doi { | ||
| 75 | u32 doi; | ||
| 76 | u32 type; | ||
| 77 | union { | ||
| 78 | struct cipso_v4_std_map_tbl *std; | ||
| 79 | } map; | ||
| 80 | u8 tags[CIPSO_V4_TAG_MAXCNT]; | ||
| 81 | |||
| 82 | u32 valid; | ||
| 83 | struct list_head list; | ||
| 84 | struct rcu_head rcu; | ||
| 85 | struct list_head dom_list; | ||
| 86 | }; | ||
| 87 | |||
| 88 | /* Standard CIPSO mapping table */ | ||
| 89 | /* NOTE: the highest order bit (i.e. 0x80000000) is an 'invalid' flag, if the | ||
| 90 | * bit is set then consider that value as unspecified, meaning the | ||
| 91 | * mapping for that particular level/category is invalid */ | ||
| 92 | struct cipso_v4_std_map_tbl { | ||
| 93 | struct { | ||
| 94 | u32 *cipso; | ||
| 95 | u32 *local; | ||
| 96 | u32 cipso_size; | ||
| 97 | u32 local_size; | ||
| 98 | } lvl; | ||
| 99 | struct { | ||
| 100 | u32 *cipso; | ||
| 101 | u32 *local; | ||
| 102 | u32 cipso_size; | ||
| 103 | u32 local_size; | ||
| 104 | } cat; | ||
| 105 | }; | ||
| 106 | |||
| 107 | /* | ||
| 108 | * Sysctl Variables | ||
| 109 | */ | ||
| 110 | |||
| 111 | #ifdef CONFIG_NETLABEL | ||
| 112 | extern int cipso_v4_cache_enabled; | ||
| 113 | extern int cipso_v4_cache_bucketsize; | ||
| 114 | extern int cipso_v4_rbm_optfmt; | ||
| 115 | extern int cipso_v4_rbm_strictvalid; | ||
| 116 | #endif | ||
| 117 | |||
| 118 | /* | ||
| 119 | * Helper Functions | ||
| 120 | */ | ||
| 121 | |||
| 122 | #define CIPSO_V4_OPTEXIST(x) (IPCB(x)->opt.cipso != 0) | ||
| 123 | #define CIPSO_V4_OPTPTR(x) ((x)->nh.raw + IPCB(x)->opt.cipso) | ||
| 124 | |||
| 125 | /* | ||
| 126 | * DOI List Functions | ||
| 127 | */ | ||
| 128 | |||
| 129 | #ifdef CONFIG_NETLABEL | ||
| 130 | int cipso_v4_doi_add(struct cipso_v4_doi *doi_def); | ||
| 131 | int cipso_v4_doi_remove(u32 doi, void (*callback) (struct rcu_head * head)); | ||
| 132 | struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi); | ||
| 133 | struct sk_buff *cipso_v4_doi_dump_all(size_t headroom); | ||
| 134 | struct sk_buff *cipso_v4_doi_dump(u32 doi, size_t headroom); | ||
| 135 | int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain); | ||
| 136 | int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def, | ||
| 137 | const char *domain); | ||
| 138 | #else | ||
| 139 | static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) | ||
| 140 | { | ||
| 141 | return -ENOSYS; | ||
| 142 | } | ||
| 143 | |||
| 144 | static inline int cipso_v4_doi_remove(u32 doi, | ||
| 145 | void (*callback) (struct rcu_head * head)) | ||
| 146 | { | ||
| 147 | return 0; | ||
| 148 | } | ||
| 149 | |||
| 150 | static inline struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi) | ||
| 151 | { | ||
| 152 | return NULL; | ||
| 153 | } | ||
| 154 | |||
| 155 | static inline struct sk_buff *cipso_v4_doi_dump_all(size_t headroom) | ||
| 156 | { | ||
| 157 | return NULL; | ||
| 158 | } | ||
| 159 | |||
| 160 | static inline struct sk_buff *cipso_v4_doi_dump(u32 doi, size_t headroom) | ||
| 161 | { | ||
| 162 | return NULL; | ||
| 163 | } | ||
| 164 | |||
| 165 | static inline int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, | ||
| 166 | const char *domain) | ||
| 167 | { | ||
| 168 | return -ENOSYS; | ||
| 169 | } | ||
| 170 | |||
| 171 | static inline int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def, | ||
| 172 | const char *domain) | ||
| 173 | { | ||
| 174 | return 0; | ||
| 175 | } | ||
| 176 | #endif /* CONFIG_NETLABEL */ | ||
| 177 | |||
| 178 | /* | ||
| 179 | * Label Mapping Cache Functions | ||
| 180 | */ | ||
| 181 | |||
| 182 | #ifdef CONFIG_NETLABEL | ||
| 183 | void cipso_v4_cache_invalidate(void); | ||
| 184 | int cipso_v4_cache_add(const struct sk_buff *skb, | ||
| 185 | const struct netlbl_lsm_secattr *secattr); | ||
| 186 | #else | ||
| 187 | static inline void cipso_v4_cache_invalidate(void) | ||
| 188 | { | ||
| 189 | return; | ||
| 190 | } | ||
| 191 | |||
| 192 | static inline int cipso_v4_cache_add(const struct sk_buff *skb, | ||
| 193 | const struct netlbl_lsm_secattr *secattr) | ||
| 194 | { | ||
| 195 | return 0; | ||
| 196 | } | ||
| 197 | #endif /* CONFIG_NETLABEL */ | ||
| 198 | |||
| 199 | /* | ||
| 200 | * Protocol Handling Functions | ||
| 201 | */ | ||
| 202 | |||
| 203 | #ifdef CONFIG_NETLABEL | ||
| 204 | void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway); | ||
| 205 | int cipso_v4_socket_setattr(const struct socket *sock, | ||
| 206 | const struct cipso_v4_doi *doi_def, | ||
| 207 | const struct netlbl_lsm_secattr *secattr); | ||
| 208 | int cipso_v4_socket_getattr(const struct socket *sock, | ||
| 209 | struct netlbl_lsm_secattr *secattr); | ||
| 210 | int cipso_v4_skbuff_getattr(const struct sk_buff *skb, | ||
| 211 | struct netlbl_lsm_secattr *secattr); | ||
| 212 | int cipso_v4_validate(unsigned char **option); | ||
| 213 | #else | ||
| 214 | static inline void cipso_v4_error(struct sk_buff *skb, | ||
| 215 | int error, | ||
| 216 | u32 gateway) | ||
| 217 | { | ||
| 218 | return; | ||
| 219 | } | ||
| 220 | |||
| 221 | static inline int cipso_v4_socket_setattr(const struct socket *sock, | ||
| 222 | const struct cipso_v4_doi *doi_def, | ||
| 223 | const struct netlbl_lsm_secattr *secattr) | ||
| 224 | { | ||
| 225 | return -ENOSYS; | ||
| 226 | } | ||
| 227 | |||
| 228 | static inline int cipso_v4_socket_getattr(const struct socket *sock, | ||
| 229 | struct netlbl_lsm_secattr *secattr) | ||
| 230 | { | ||
| 231 | return -ENOSYS; | ||
| 232 | } | ||
| 233 | |||
| 234 | static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb, | ||
| 235 | struct netlbl_lsm_secattr *secattr) | ||
| 236 | { | ||
| 237 | return -ENOSYS; | ||
| 238 | } | ||
| 239 | |||
| 240 | static inline int cipso_v4_validate(unsigned char **option) | ||
| 241 | { | ||
| 242 | return -ENOSYS; | ||
| 243 | } | ||
| 244 | #endif /* CONFIG_NETLABEL */ | ||
| 245 | |||
| 246 | #endif /* _CIPSO_IPV4_H */ | ||
| @@ -22,7 +22,7 @@ struct dn_kern_rta · 21 unmodified lines | |||
| 22 | }; | 22 | }; |
| 23 | 23 | ||
| 24 | struct dn_fib_res { | 24 | struct dn_fib_res { |
| 25 | struct dn_fib_rule *r; | 25 | struct fib_rule *r; |
| 26 | struct dn_fib_info *fi; | 26 | struct dn_fib_info *fi; |
| 27 | unsigned char prefixlen; | 27 | unsigned char prefixlen; |
| 28 | unsigned char nh_sel; | 28 | unsigned char nh_sel; |
| @@ -94,7 +94,8 @@ struct dn_fib_node { · 65 unmodified lines | |||
| 94 | 94 | ||
| 95 | 95 | ||
| 96 | struct dn_fib_table { | 96 | struct dn_fib_table { |
| 97 | int n; | 97 | struct hlist_node hlist; |
| 98 | u32 n; | ||
| 98 | 99 | ||
| 99 | int (*insert)(struct dn_fib_table *t, struct rtmsg *r, | 100 | int (*insert)(struct dn_fib_table *t, struct rtmsg *r, |
| 100 | struct dn_kern_rta *rta, struct nlmsghdr *n, | 101 | struct dn_kern_rta *rta, struct nlmsghdr *n, |
| @@ -130,14 +131,11 @@ extern __le16 dn_fib_get_attr16(struct rtattr *attr, int attrlen, int type); · 29 unmodified lines | |||
| 130 | extern void dn_fib_flush(void); | 131 | extern void dn_fib_flush(void); |
| 131 | extern void dn_fib_select_multipath(const struct flowi *fl, | 132 | extern void dn_fib_select_multipath(const struct flowi *fl, |
| 132 | struct dn_fib_res *res); | 133 | struct dn_fib_res *res); |
| 133 | extern int dn_fib_sync_down(__le16 local, struct net_device *dev, | ||
| 134 | int force); | ||
| 135 | extern int dn_fib_sync_up(struct net_device *dev); | ||
| 136 | 134 | ||
| 137 | /* | 135 | /* |
| 138 | * dn_tables.c | 136 | * dn_tables.c |
| 139 | */ | 137 | */ |
| 140 | extern struct dn_fib_table *dn_fib_get_table(int n, int creat); | 138 | extern struct dn_fib_table *dn_fib_get_table(u32 n, int creat); |
| 141 | extern struct dn_fib_table *dn_fib_empty_table(void); | 139 | extern struct dn_fib_table *dn_fib_empty_table(void); |
| 142 | extern void dn_fib_table_init(void); | 140 | extern void dn_fib_table_init(void); |
| 143 | extern void dn_fib_table_cleanup(void); | 141 | extern void dn_fib_table_cleanup(void); |
| @@ -147,10 +145,8 @@ extern void dn_fib_table_cleanup(void); · 3 unmodified lines | |||
| 147 | */ | 145 | */ |
| 148 | extern void dn_fib_rules_init(void); | 146 | extern void dn_fib_rules_init(void); |
| 149 | extern void dn_fib_rules_cleanup(void); | 147 | extern void dn_fib_rules_cleanup(void); |
| 150 | extern void dn_fib_rule_put(struct dn_fib_rule *); | ||
| 151 | extern __le16 dn_fib_rules_policy(__le16 saddr, struct dn_fib_res *res, unsigned *flags); | ||
| 152 | extern unsigned dnet_addr_type(__le16 addr); | 148 | extern unsigned dnet_addr_type(__le16 addr); |
| 153 | extern int dn_fib_lookup(const struct flowi *fl, struct dn_fib_res *res); | 149 | extern int dn_fib_lookup(struct flowi *fl, struct dn_fib_res *res); |
| 154 | 150 | ||
| 155 | /* | 151 | /* |
| 156 | * rtnetlink interface | 152 | * rtnetlink interface |
| @@ -176,11 +172,9 @@ static inline void dn_fib_res_put(struct dn_fib_res *res) · 19 unmodified lines | |||
| 176 | if (res->fi) | 172 | if (res->fi) |
| 177 | dn_fib_info_put(res->fi); | 173 | dn_fib_info_put(res->fi); |
| 178 | if (res->r) | 174 | if (res->r) |
| 179 | dn_fib_rule_put(res->r); | 175 | fib_rule_put(res->r); |
| 180 | } | 176 | } |
| 181 | 177 | ||
| 182 | extern struct dn_fib_table *dn_fib_tables[]; | ||
| 183 | |||
| 184 | #else /* Endnode */ | 178 | #else /* Endnode */ |
| 185 | 179 | ||
| 186 | #define dn_fib_init() do { } while(0) | 180 | #define dn_fib_init() do { } while(0) |
| @@ -54,6 +54,7 @@ struct dst_entry · 53 unmodified lines | |||
| 54 | unsigned long expires; | 54 | unsigned long expires; |
| 55 | 55 | ||
| 56 | unsigned short header_len; /* more space at head required */ | 56 | unsigned short header_len; /* more space at head required */ |
| 57 | unsigned short nfheader_len; /* more non-fragment space at head required */ | ||
| 57 | unsigned short trailer_len; /* space to reserve at tail */ | 58 | unsigned short trailer_len; /* space to reserve at tail */ |
| 58 | 59 | ||
| 59 | u32 metrics[RTAX_MAX]; | 60 | u32 metrics[RTAX_MAX]; |
| @@ -15,13 +15,14 @@ struct esp_data · 14 unmodified lines | |||
| 15 | struct { | 15 | struct { |
| 16 | u8 *key; /* Key */ | 16 | u8 *key; /* Key */ |
| 17 | int key_len; /* Key length */ | 17 | int key_len; /* Key length */ |
| 18 | u8 *ivec; /* ivec buffer */ | 18 | int padlen; /* 0..255 */ |
| 19 | /* ivlen is offset from enc_data, where encrypted data start. | 19 | /* ivlen is offset from enc_data, where encrypted data start. |
| 20 | * It is logically different of crypto_tfm_alg_ivsize(tfm). | 20 | * It is logically different of crypto_tfm_alg_ivsize(tfm). |
| 21 | * We assume that it is either zero (no ivec), or | 21 | * We assume that it is either zero (no ivec), or |
| 22 | * >= crypto_tfm_alg_ivsize(tfm). */ | 22 | * >= crypto_tfm_alg_ivsize(tfm). */ |
| 23 | int ivlen; | 23 | int ivlen; |
| 24 | int padlen; /* 0..255 */ | 24 | int ivinitted; |
| 25 | u8 *ivec; /* ivec buffer */ | ||
| 25 | struct crypto_blkcipher *tfm; /* crypto handle */ | 26 | struct crypto_blkcipher *tfm; /* crypto handle */ |
| 26 | } conf; | 27 | } conf; |
| 27 | 28 | ||
| @@ -0,0 +1,97 @@ | |||
| 1 | #ifndef __NET_FIB_RULES_H | ||
| 2 | #define __NET_FIB_RULES_H | ||
| 3 | |||
| 4 | #include <linux/types.h> | ||
| 5 | #include <linux/netdevice.h> | ||
| 6 | #include <linux/fib_rules.h> | ||
| 7 | #include <net/flow.h> | ||
| 8 | #include <net/netlink.h> | ||
| 9 | |||
| 10 | struct fib_rule | ||
| 11 | { | ||
| 12 | struct list_head list; | ||
| 13 | atomic_t refcnt; | ||
| 14 | int ifindex; | ||
| 15 | char ifname[IFNAMSIZ]; | ||
| 16 | u32 pref; | ||
| 17 | u32 flags; | ||
| 18 | u32 table; | ||
| 19 | u8 action; | ||
| 20 | struct rcu_head rcu; | ||
| 21 | }; | ||
| 22 | |||
| 23 | struct fib_lookup_arg | ||
| 24 | { | ||
| 25 | void *lookup_ptr; | ||
| 26 | void *result; | ||
| 27 | struct fib_rule *rule; | ||
| 28 | }; | ||
| 29 | |||
| 30 | struct fib_rules_ops | ||
| 31 | { | ||
| 32 | int family; | ||
| 33 | struct list_head list; | ||
| 34 | int rule_size; | ||
| 35 | |||
| 36 | int (*action)(struct fib_rule *, | ||
| 37 | struct flowi *, int, | ||
| 38 | struct fib_lookup_arg *); | ||
| 39 | int (*match)(struct fib_rule *, | ||
| 40 | struct flowi *, int); | ||
| 41 | int (*configure)(struct fib_rule *, | ||
| 42 | struct sk_buff *, | ||
| 43 | struct nlmsghdr *, | ||
| 44 | struct fib_rule_hdr *, | ||
| 45 | struct nlattr **); | ||
| 46 | int (*compare)(struct fib_rule *, | ||
| 47 | struct fib_rule_hdr *, | ||
| 48 | struct nlattr **); | ||
| 49 | int (*fill)(struct fib_rule *, struct sk_buff *, | ||
| 50 | struct nlmsghdr *, | ||
| 51 | struct fib_rule_hdr *); | ||
| 52 | u32 (*default_pref)(void); | ||
| 53 | |||
| 54 | int nlgroup; | ||
| 55 | struct nla_policy *policy; | ||
| 56 | struct list_head *rules_list; | ||
| 57 | struct module *owner; | ||
| 58 | }; | ||
| 59 | |||
| 60 | static inline void fib_rule_get(struct fib_rule *rule) | ||
| 61 | { | ||
| 62 | atomic_inc(&rule->refcnt); | ||
| 63 | } | ||
| 64 | |||
| 65 | static inline void fib_rule_put_rcu(struct rcu_head *head) | ||
| 66 | { | ||
| 67 | struct fib_rule *rule = container_of(head, struct fib_rule, rcu); | ||
| 68 | kfree(rule); | ||
| 69 | } | ||
| 70 | |||
| 71 | static inline void fib_rule_put(struct fib_rule *rule) | ||
| 72 | { | ||
| 73 | if (atomic_dec_and_test(&rule->refcnt)) | ||
| 74 | call_rcu(&rule->rcu, fib_rule_put_rcu); | ||
| 75 | } | ||
| 76 | |||
| 77 | static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla) | ||
| 78 | { | ||
| 79 | if (nla[FRA_TABLE]) | ||
| 80 | return nla_get_u32(nla[FRA_TABLE]); | ||
| 81 | return frh->table; | ||
| 82 | } | ||
| 83 | |||
| 84 | extern int fib_rules_register(struct fib_rules_ops *); | ||
| 85 | extern int fib_rules_unregister(struct fib_rules_ops *); | ||
| 86 | |||
| 87 | extern int fib_rules_lookup(struct fib_rules_ops *, | ||
| 88 | struct flowi *, int flags, | ||
| 89 | struct fib_lookup_arg *); | ||
| 90 | |||
| 91 | extern int fib_nl_newrule(struct sk_buff *, | ||
| 92 | struct nlmsghdr *, void *); | ||
| 93 | extern int fib_nl_delrule(struct sk_buff *, | ||
| 94 | struct nlmsghdr *, void *); | ||
| 95 | extern int fib_rules_dump(struct sk_buff *, | ||
| 96 | struct netlink_callback *, int); | ||
| 97 | #endif | ||
| @@ -26,6 +26,7 @@ struct flowi { · 25 unmodified lines | |||
| 26 | struct { | 26 | struct { |
| 27 | struct in6_addr daddr; | 27 | struct in6_addr daddr; |
| 28 | struct in6_addr saddr; | 28 | struct in6_addr saddr; |
| 29 | __u32 fwmark; | ||
| 29 | __u32 flowlabel; | 30 | __u32 flowlabel; |
| 30 | } ip6_u; | 31 | } ip6_u; |
| 31 | 32 | ||
| @@ -42,6 +43,7 @@ struct flowi { · 10 unmodified lines | |||
| 42 | #define fld_scope nl_u.dn_u.scope | 43 | #define fld_scope nl_u.dn_u.scope |
| 43 | #define fl6_dst nl_u.ip6_u.daddr | 44 | #define fl6_dst nl_u.ip6_u.daddr |
| 44 | #define fl6_src nl_u.ip6_u.saddr | 45 | #define fl6_src nl_u.ip6_u.saddr |
| 46 | #define fl6_fwmark nl_u.ip6_u.fwmark | ||
| 45 | #define fl6_flowlabel nl_u.ip6_u.flowlabel | 47 | #define fl6_flowlabel nl_u.ip6_u.flowlabel |
| 46 | #define fl4_dst nl_u.ip4_u.daddr | 48 | #define fl4_dst nl_u.ip4_u.daddr |
| 47 | #define fl4_src nl_u.ip4_u.saddr | 49 | #define fl4_src nl_u.ip4_u.saddr |
| @@ -72,12 +74,22 @@ struct flowi { · 24 unmodified lines | |||
| 72 | } dnports; | 74 | } dnports; |
| 73 | 75 | ||
| 74 | __u32 spi; | 76 | __u32 spi; |
| 77 | |||
| 78 | #ifdef CONFIG_IPV6_MIP6 | ||
| 79 | struct { | ||
| 80 | __u8 type; | ||
| 81 | } mht; | ||
| 82 | #endif | ||
| 75 | } uli_u; | 83 | } uli_u; |
| 76 | #define fl_ip_sport uli_u.ports.sport | 84 | #define fl_ip_sport uli_u.ports.sport |
| 77 | #define fl_ip_dport uli_u.ports.dport | 85 | #define fl_ip_dport uli_u.ports.dport |
| 78 | #define fl_icmp_type uli_u.icmpt.type | 86 | #define fl_icmp_type uli_u.icmpt.type |
| 79 | #define fl_icmp_code uli_u.icmpt.code | 87 | #define fl_icmp_code uli_u.icmpt.code |
| 80 | #define fl_ipsec_spi uli_u.spi | 88 | #define fl_ipsec_spi uli_u.spi |
| 89 | #ifdef CONFIG_IPV6_MIP6 | ||
| 90 | #define fl_mh_type uli_u.mht.type | ||
| 91 | #endif | ||
| 92 | __u32 secid; /* used by xfrm; see secid.txt */ | ||
| 81 | } __attribute__((__aligned__(BITS_PER_LONG/8))); | 93 | } __attribute__((__aligned__(BITS_PER_LONG/8))); |
| 82 | 94 | ||
| 83 | #define FLOW_DIR_IN 0 | 95 | #define FLOW_DIR_IN 0 |
| @@ -85,10 +97,10 @@ struct flowi { · 1 unmodified line | |||
| 85 | #define FLOW_DIR_FWD 2 | 97 | #define FLOW_DIR_FWD 2 |
| 86 | 98 | ||
| 87 | struct sock; | 99 | struct sock; |
| 88 | typedef void (*flow_resolve_t)(struct flowi *key, u32 sk_sid, u16 family, u8 dir, | 100 | typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir, |
| 89 | void **objp, atomic_t **obj_refp); | 101 | void **objp, atomic_t **obj_refp); |
| 90 | 102 | ||
| 91 | extern void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir, | 103 | extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, |
| 92 | flow_resolve_t resolver); | 104 | flow_resolve_t resolver); |
| 93 | extern void flow_cache_flush(void); | 105 | extern void flow_cache_flush(void); |
| 94 | extern atomic_t flow_cache_genid; | 106 | extern atomic_t flow_cache_genid; |
| @@ -27,8 +27,6 @@ struct genl_family · 26 unmodified lines | |||
| 27 | struct list_head family_list; /* private */ | 27 | struct list_head family_list; /* private */ |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | #define GENL_ADMIN_PERM 0x01 | ||
| 31 | |||
| 32 | /** | 30 | /** |
| 33 | * struct genl_info - receiving information | 31 | * struct genl_info - receiving information |
| 34 | * @snd_seq: sending sequence number | 32 | * @snd_seq: sending sequence number |
| @@ -133,11 +131,12 @@ static inline int genlmsg_cancel(struct sk_buff *skb, void *hdr) · 98 unmodified lines | |||
| 133 | * @skb: netlink message as socket buffer | 131 | * @skb: netlink message as socket buffer |
| 134 | * @pid: own netlink pid to avoid sending to yourself | 132 | * @pid: own netlink pid to avoid sending to yourself |
| 135 | * @group: multicast group id | 133 | * @group: multicast group id |
| 134 | * @flags: allocation flags | ||
| 136 | */ | 135 | */ |
| 137 | static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid, | 136 | static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid, |
| 138 | unsigned int group) | 137 | unsigned int group, gfp_t flags) |
| 139 | { | 138 | { |
| 140 | return nlmsg_multicast(genl_sock, skb, pid, group); | 139 | return nlmsg_multicast(genl_sock, skb, pid, group, flags); |
| 141 | } | 140 | } |
| 142 | 141 | ||
| 143 | /** | 142 | /** |
| @@ -189,6 +189,7 @@ struct inet6_dev · 188 unmodified lines | |||
| 189 | struct ipv6_devconf cnf; | 189 | struct ipv6_devconf cnf; |
| 190 | struct ipv6_devstat stats; | 190 | struct ipv6_devstat stats; |
| 191 | unsigned long tstamp; /* ipv6InterfaceTable update timestamp */ | 191 | unsigned long tstamp; /* ipv6InterfaceTable update timestamp */ |
| 192 | struct rcu_head rcu; | ||
| 192 | }; | 193 | }; |
| 193 | 194 | ||
| 194 | extern struct ipv6_devconf ipv6_devconf; | 195 | extern struct ipv6_devconf ipv6_devconf; |
| @@ -147,7 +147,8 @@ extern struct sock *inet_csk_clone(struct sock *sk, · 146 unmodified lines | |||
| 147 | enum inet_csk_ack_state_t { | 147 | enum inet_csk_ack_state_t { |
| 148 | ICSK_ACK_SCHED = 1, | 148 | ICSK_ACK_SCHED = 1, |
| 149 | ICSK_ACK_TIMER = 2, | 149 | ICSK_ACK_TIMER = 2, |
| 150 | ICSK_ACK_PUSHED = 4 | 150 | ICSK_ACK_PUSHED = 4, |
| 151 | ICSK_ACK_PUSHED2 = 8 | ||
| 151 | }; | 152 | }; |
| 152 | 153 | ||
| 153 | extern void inet_csk_init_xmit_timers(struct sock *sk, | 154 | extern void inet_csk_init_xmit_timers(struct sock *sk, |
| @@ -271,38 +271,15 @@ static inline int inet_iif(const struct sk_buff *skb) · 270 unmodified lines | |||
| 271 | return ((struct rtable *)skb->dst)->rt_iif; | 271 | return ((struct rtable *)skb->dst)->rt_iif; |
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | extern struct sock *__inet_lookup_listener(const struct hlist_head *head, | 274 | extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo, |
| 275 | const u32 daddr, | 275 | const u32 daddr, |
| 276 | const unsigned short hnum, | 276 | const unsigned short hnum, |
| 277 | const int dif); | 277 | const int dif); |
| 278 | 278 | ||
| 279 | /* Optimize the common listener case. */ | 279 | static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo, |
| 280 | static inline struct sock * | 280 | u32 daddr, u16 dport, int dif) |
| 281 | inet_lookup_listener(struct inet_hashinfo *hashinfo, | ||
| 282 | const u32 daddr, | ||
| 283 | const unsigned short hnum, const int dif) | ||
| 284 | { | 281 | { |
| 285 | struct sock *sk = NULL; | 282 | return __inet_lookup_listener(hashinfo, daddr, ntohs(dport), dif); |
| 286 | const struct hlist_head *head; | ||
| 287 | |||
| 288 | read_lock(&hashinfo->lhash_lock); | ||
| 289 | head = &hashinfo->listening_hash[inet_lhashfn(hnum)]; | ||
| 290 | if (!hlist_empty(head)) { | ||
| 291 | const struct inet_sock *inet = inet_sk((sk = __sk_head(head))); | ||
| 292 | |||
| 293 | if (inet->num == hnum && !sk->sk_node.next && | ||
| 294 | (!inet->rcv_saddr || inet->rcv_saddr == daddr) && | ||
| 295 | (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) && | ||
| 296 | !sk->sk_bound_dev_if) | ||
| 297 | goto sherry_cache; | ||
| 298 | sk = __inet_lookup_listener(head, daddr, hnum, dif); | ||
| 299 | } | ||
| 300 | if (sk) { | ||
| 301 | sherry_cache: | ||
| 302 | sock_hold(sk); | ||
| 303 | } | ||
| 304 | read_unlock(&hashinfo->lhash_lock); | ||
| 305 | return sk; | ||
| 306 | } | 283 | } |
| 307 | 284 | ||
| 308 | /* Socket demux engine toys. */ | 285 | /* Socket demux engine toys. */ |
| @@ -391,14 +368,25 @@ hit: · 82 unmodified lines | |||
| 391 | goto out; | 368 | goto out; |
| 392 | } | 369 | } |
| 393 | 370 | ||
| 371 | static inline struct sock * | ||
| 372 | inet_lookup_established(struct inet_hashinfo *hashinfo, | ||
| 373 | const u32 saddr, const u16 sport, | ||
| 374 | const u32 daddr, const u16 dport, | ||
| 375 | const int dif) | ||
| 376 | { | ||
| 377 | return __inet_lookup_established(hashinfo, saddr, sport, daddr, | ||
| 378 | ntohs(dport), dif); | ||
| 379 | } | ||
| 380 | |||
| 394 | static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo, | 381 | static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo, |
| 395 | const u32 saddr, const u16 sport, | 382 | const u32 saddr, const u16 sport, |
| 396 | const u32 daddr, const u16 hnum, | 383 | const u32 daddr, const u16 dport, |
| 397 | const int dif) | 384 | const int dif) |
| 398 | { | 385 | { |
| 386 | u16 hnum = ntohs(dport); | ||
| 399 | struct sock *sk = __inet_lookup_established(hashinfo, saddr, sport, daddr, | 387 | struct sock *sk = __inet_lookup_established(hashinfo, saddr, sport, daddr, |
| 400 | hnum, dif); | 388 | hnum, dif); |
| 401 | return sk ? : inet_lookup_listener(hashinfo, daddr, hnum, dif); | 389 | return sk ? : __inet_lookup_listener(hashinfo, daddr, hnum, dif); |
| 402 | } | 390 | } |
| 403 | 391 | ||
| 404 | static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo, | 392 | static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo, |
| @@ -409,7 +397,7 @@ static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo, · 4 unmodified lines | |||
| 409 | struct sock *sk; | 397 | struct sock *sk; |
| 410 | 398 | ||
| 411 | local_bh_disable(); | 399 | local_bh_disable(); |
| 412 | sk = __inet_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif); | 400 | sk = __inet_lookup(hashinfo, saddr, sport, daddr, dport, dif); |
| 413 | local_bh_enable(); | 401 | local_bh_enable(); |
| 414 | 402 | ||
| 415 | return sk; | 403 | return sk; |
| @@ -27,7 +27,6 @@ · 26 unmodified lines | |||
| 27 | /** struct ip_options - IP Options | 27 | /** struct ip_options - IP Options |
| 28 | * | 28 | * |
| 29 | * @faddr - Saved first hop address | 29 | * @faddr - Saved first hop address |
| 30 | * @is_setbyuser - Set by setsockopt? | ||
| 31 | * @is_data - Options in __data, rather than skb | 30 | * @is_data - Options in __data, rather than skb |
| 32 | * @is_strictroute - Strict source route | 31 | * @is_strictroute - Strict source route |
| 33 | * @srr_is_hit - Packet destination addr was our one | 32 | * @srr_is_hit - Packet destination addr was our one |
| @@ -42,8 +41,7 @@ struct ip_options { · 8 unmodified lines | |||
| 42 | unsigned char srr; | 41 | unsigned char srr; |
| 43 | unsigned char rr; | 42 | unsigned char rr; |
| 44 | unsigned char ts; | 43 | unsigned char ts; |
| 45 | unsigned char is_setbyuser:1, | 44 | unsigned char is_data:1, |
| 46 | is_data:1, | ||
| 47 | is_strictroute:1, | 45 | is_strictroute:1, |
| 48 | srr_is_hit:1, | 46 | srr_is_hit:1, |
| 49 | is_changed:1, | 47 | is_changed:1, |
| @@ -51,7 +49,7 @@ struct ip_options { · 1 unmodified line | |||
| 51 | ts_needtime:1, | 49 | ts_needtime:1, |
| 52 | ts_needaddr:1; | 50 | ts_needaddr:1; |
| 53 | unsigned char router_alert; | 51 | unsigned char router_alert; |
| 54 | unsigned char __pad1; | 52 | unsigned char cipso; |
| 55 | unsigned char __pad2; | 53 | unsigned char __pad2; |
| 56 | unsigned char __data[0]; | 54 | unsigned char __data[0]; |
| 57 | }; | 55 | }; |
| @@ -16,14 +16,35 @@ · 15 unmodified lines | |||
| 16 | #ifdef __KERNEL__ | 16 | #ifdef __KERNEL__ |
| 17 | 17 | ||
| 18 | #include <linux/ipv6_route.h> | 18 | #include <linux/ipv6_route.h> |
| 19 | |||
| 20 | #include <net/dst.h> | ||
| 21 | #include <net/flow.h> | ||
| 22 | #include <linux/rtnetlink.h> | 19 | #include <linux/rtnetlink.h> |
| 23 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
| 21 | #include <net/dst.h> | ||
| 22 | #include <net/flow.h> | ||
| 23 | #include <net/netlink.h> | ||
| 24 | 24 | ||
| 25 | struct rt6_info; | 25 | struct rt6_info; |
| 26 | 26 | ||
| 27 | struct fib6_config | ||
| 28 | { | ||
| 29 | u32 fc_table; | ||
| 30 | u32 fc_metric; | ||
| 31 | int fc_dst_len; | ||
| 32 | int fc_src_len; | ||
| 33 | int fc_ifindex; | ||
| 34 | u32 fc_flags; | ||
| 35 | u32 fc_protocol; | ||
| 36 | |||
| 37 | struct in6_addr fc_dst; | ||
| 38 | struct in6_addr fc_src; | ||
| 39 | struct in6_addr fc_gateway; | ||
| 40 | |||
| 41 | unsigned long fc_expires; | ||
| 42 | struct nlattr *fc_mx; | ||
| 43 | int fc_mx_len; | ||
| 44 | |||
| 45 | struct nl_info fc_nlinfo; | ||
| 46 | }; | ||
| 47 | |||
| 27 | struct fib6_node | 48 | struct fib6_node |
| 28 | { | 49 | { |
| 29 | struct fib6_node *parent; | 50 | struct fib6_node *parent; |
| @@ -39,6 +60,11 @@ struct fib6_node · 9 unmodified lines | |||
| 39 | __u32 fn_sernum; | 60 | __u32 fn_sernum; |
| 40 | }; | 61 | }; |
| 41 | 62 | ||
| 63 | #ifndef CONFIG_IPV6_SUBTREES | ||
| 64 | #define FIB6_SUBTREE(fn) NULL | ||
| 65 | #else | ||
| 66 | #define FIB6_SUBTREE(fn) ((fn)->subtree) | ||
| 67 | #endif | ||
| 42 | 68 | ||
| 43 | /* | 69 | /* |
| 44 | * routing information | 70 | * routing information |
| @@ -51,6 +77,8 @@ struct rt6key · 6 unmodified lines | |||
| 51 | int plen; | 77 | int plen; |
| 52 | }; | 78 | }; |
| 53 | 79 | ||
| 80 | struct fib6_table; | ||
| 81 | |||
| 54 | struct rt6_info | 82 | struct rt6_info |
| 55 | { | 83 | { |
| 56 | union { | 84 | union { |
| @@ -71,6 +99,7 @@ struct rt6_info · 14 unmodified lines | |||
| 71 | u32 rt6i_flags; | 99 | u32 rt6i_flags; |
| 72 | u32 rt6i_metric; | 100 | u32 rt6i_metric; |
| 73 | atomic_t rt6i_ref; | 101 | atomic_t rt6i_ref; |
| 102 | struct fib6_table *rt6i_table; | ||
| 74 | 103 | ||
| 75 | struct rt6key rt6i_dst; | 104 | struct rt6key rt6i_dst; |
| 76 | struct rt6key rt6i_src; | 105 | struct rt6key rt6i_src; |
| @@ -89,28 +118,6 @@ struct fib6_walker_t · 12 unmodified lines | |||
| 89 | void *args; | 118 | void *args; |
| 90 | }; | 119 | }; |
| 91 | 120 | ||
| 92 | extern struct fib6_walker_t fib6_walker_list; | ||
| 93 | extern rwlock_t fib6_walker_lock; | ||
| 94 | |||
| 95 | static inline void fib6_walker_link(struct fib6_walker_t *w) | ||
| 96 | { | ||
| 97 | write_lock_bh(&fib6_walker_lock); | ||
| 98 | w->next = fib6_walker_list.next; | ||
| 99 | w->prev = &fib6_walker_list; | ||
| 100 | w->next->prev = w; | ||
| 101 | w->prev->next = w; | ||
| 102 | write_unlock_bh(&fib6_walker_lock); | ||
| 103 | } | ||
| 104 | |||
| 105 | static inline void fib6_walker_unlink(struct fib6_walker_t *w) | ||
| 106 | { | ||
| 107 | write_lock_bh(&fib6_walker_lock); | ||
| 108 | w->next->prev = w->prev; | ||
| 109 | w->prev->next = w->next; | ||
| 110 | w->prev = w->next = w; | ||
| 111 | write_unlock_bh(&fib6_walker_lock); | ||
| 112 | } | ||
| 113 | |||
| 114 | struct rt6_statistics { | 121 | struct rt6_statistics { |
| 115 | __u32 fib_nodes; | 122 | __u32 fib_nodes; |
| 116 | __u32 fib_route_nodes; | 123 | __u32 fib_route_nodes; |
| @@ -143,12 +150,41 @@ struct rt6_statistics { · 26 unmodified lines | |||
| 143 | 150 | ||
| 144 | typedef void (*f_pnode)(struct fib6_node *fn, void *); | 151 | typedef void (*f_pnode)(struct fib6_node *fn, void *); |
| 145 | 152 | ||
| 146 | extern struct fib6_node ip6_routing_table; | 153 | struct fib6_table { |
| 154 | struct hlist_node tb6_hlist; | ||
| 155 | u32 tb6_id; | ||
| 156 | rwlock_t tb6_lock; | ||
| 157 | struct fib6_node tb6_root; | ||
| 158 | }; | ||
| 159 | |||
| 160 | #define RT6_TABLE_UNSPEC RT_TABLE_UNSPEC | ||
| 161 | #define RT6_TABLE_MAIN RT_TABLE_MAIN | ||
| 162 | #define RT6_TABLE_DFLT RT6_TABLE_MAIN | ||
| 163 | #define RT6_TABLE_INFO RT6_TABLE_MAIN | ||
| 164 | #define RT6_TABLE_PREFIX RT6_TABLE_MAIN | ||
| 165 | |||
| 166 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
| 167 | #define FIB6_TABLE_MIN 1 | ||
| 168 | #define FIB6_TABLE_MAX RT_TABLE_MAX | ||
| 169 | #define RT6_TABLE_LOCAL RT_TABLE_LOCAL | ||
| 170 | #else | ||
| 171 | #define FIB6_TABLE_MIN RT_TABLE_MAIN | ||
| 172 | #define FIB6_TABLE_MAX FIB6_TABLE_MIN | ||
| 173 | #define RT6_TABLE_LOCAL RT6_TABLE_MAIN | ||
| 174 | #endif | ||
| 175 | |||
| 176 | typedef struct rt6_info *(*pol_lookup_t)(struct fib6_table *, | ||
| 177 | struct flowi *, int); | ||
| 147 | 178 | ||
| 148 | /* | 179 | /* |
| 149 | * exported functions | 180 | * exported functions |
| 150 | */ | 181 | */ |
| 151 | 182 | ||
| 183 | extern struct fib6_table * fib6_get_table(u32 id); | ||
| 184 | extern struct fib6_table * fib6_new_table(u32 id); | ||
| 185 | extern struct dst_entry * fib6_rule_lookup(struct flowi *fl, int flags, | ||
| 186 | pol_lookup_t lookup); | ||
| 187 | |||
| 152 | extern struct fib6_node *fib6_lookup(struct fib6_node *root, | 188 | extern struct fib6_node *fib6_lookup(struct fib6_node *root, |
| 153 | struct in6_addr *daddr, | 189 | struct in6_addr *daddr, |
| 154 | struct in6_addr *saddr); | 190 | struct in6_addr *saddr); |
| @@ -157,32 +193,29 @@ struct fib6_node *fib6_locate(struct fib6_node *root, · 2 unmodified lines | |||
| 157 | struct in6_addr *daddr, int dst_len, | 193 | struct in6_addr *daddr, int dst_len, |
| 158 | struct in6_addr *saddr, int src_len); | 194 | struct in6_addr *saddr, int src_len); |
| 159 | 195 | ||
| 160 | extern void fib6_clean_tree(struct fib6_node *root, | 196 | extern void fib6_clean_all(int (*func)(struct rt6_info *, void *arg), |
| 161 | int (*func)(struct rt6_info *, void *arg), | 197 | int prune, void *arg); |
| 162 | int prune, void *arg); | ||
| 163 | |||
| 164 | extern int fib6_walk(struct fib6_walker_t *w); | ||
| 165 | extern int fib6_walk_continue(struct fib6_walker_t *w); | ||
| 166 | 198 | ||
| 167 | extern int fib6_add(struct fib6_node *root, | 199 | extern int fib6_add(struct fib6_node *root, |
| 168 | struct rt6_info *rt, | 200 | struct rt6_info *rt, |
| 169 | struct nlmsghdr *nlh, | 201 | struct nl_info *info); |
| 170 | void *rtattr, | ||
| 171 | struct netlink_skb_parms *req); | ||
| 172 | 202 | ||
| 173 | extern int fib6_del(struct rt6_info *rt, | 203 | extern int fib6_del(struct rt6_info *rt, |
| 174 | struct nlmsghdr *nlh, | 204 | struct nl_info *info); |
| 175 | void *rtattr, | ||
| 176 | struct netlink_skb_parms *req); | ||
| 177 | 205 | ||
| 178 | extern void inet6_rt_notify(int event, struct rt6_info *rt, | 206 | extern void inet6_rt_notify(int event, struct rt6_info *rt, |
| 179 | struct nlmsghdr *nlh, | 207 | struct nl_info *info); |
| 180 | struct netlink_skb_parms *req); | ||
| 181 | 208 | ||
| 182 | extern void fib6_run_gc(unsigned long dummy); | 209 | extern void fib6_run_gc(unsigned long dummy); |
| 183 | 210 | ||
| 184 | extern void fib6_gc_cleanup(void); | 211 | extern void fib6_gc_cleanup(void); |
| 185 | 212 | ||
| 186 | extern void fib6_init(void); | 213 | extern void fib6_init(void); |
| 214 | |||
| 215 | extern void fib6_rules_init(void); | ||
| 216 | extern void fib6_rules_cleanup(void); | ||
| 217 | extern int fib6_rules_dump(struct sk_buff *, | ||
| 218 | struct netlink_callback *); | ||
| 219 | |||
| 187 | #endif | 220 | #endif |
| 188 | #endif | 221 | #endif |
| @@ -32,6 +32,10 @@ struct route_info { · 31 unmodified lines | |||
| 32 | #include <linux/ip.h> | 32 | #include <linux/ip.h> |
| 33 | #include <linux/ipv6.h> | 33 | #include <linux/ipv6.h> |
| 34 | 34 | ||
| 35 | #define RT6_LOOKUP_F_IFACE 0x1 | ||
| 36 | #define RT6_LOOKUP_F_REACHABLE 0x2 | ||
| 37 | #define RT6_LOOKUP_F_HAS_SADDR 0x4 | ||
| 38 | |||
| 35 | struct pol_chain { | 39 | struct pol_chain { |
| 36 | int type; | 40 | int type; |
| 37 | int priority; | 41 | int priority; |
| @@ -41,6 +45,11 @@ struct pol_chain { · 3 unmodified lines | |||
| 41 | 45 | ||
| 42 | extern struct rt6_info ip6_null_entry; | 46 | extern struct rt6_info ip6_null_entry; |
| 43 | 47 | ||
| 48 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
| 49 | extern struct rt6_info ip6_prohibit_entry; | ||
| 50 | extern struct rt6_info ip6_blk_hole_entry; | ||
| 51 | #endif | ||
| 52 | |||
| 44 | extern int ip6_rt_gc_interval; | 53 | extern int ip6_rt_gc_interval; |
| 45 | 54 | ||
| 46 | extern void ip6_route_input(struct sk_buff *skb); | 55 | extern void ip6_route_input(struct sk_buff *skb); |
| @@ -48,25 +57,14 @@ extern void ip6_route_input(struct sk_buff *skb); · 1 unmodified line | |||
| 48 | extern struct dst_entry * ip6_route_output(struct sock *sk, | 57 | extern struct dst_entry * ip6_route_output(struct sock *sk, |
| 49 | struct flowi *fl); | 58 | struct flowi *fl); |
| 50 | 59 | ||
| 51 | extern int ip6_route_me_harder(struct sk_buff *skb); | ||
| 52 | |||
| 53 | extern void ip6_route_init(void); | 60 | extern void ip6_route_init(void); |
| 54 | extern void ip6_route_cleanup(void); | 61 | extern void ip6_route_cleanup(void); |
| 55 | 62 | ||
| 56 | extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg); | 63 | extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg); |
| 57 | 64 | ||
| 58 | extern int ip6_route_add(struct in6_rtmsg *rtmsg, | 65 | extern int ip6_route_add(struct fib6_config *cfg); |
| 59 | struct nlmsghdr *, | 66 | extern int ip6_ins_rt(struct rt6_info *); |
| 60 | void *rtattr, | 67 | extern int ip6_del_rt(struct rt6_info *); |
| 61 | struct netlink_skb_parms *req); | ||
| 62 | extern int ip6_ins_rt(struct rt6_info *, | ||
| 63 | struct nlmsghdr *, | ||
| 64 | void *rtattr, | ||
| 65 | struct netlink_skb_parms *req); | ||
| 66 | extern int ip6_del_rt(struct rt6_info *, | ||
| 67 | struct nlmsghdr *, | ||
| 68 | void *rtattr, | ||
| 69 | struct netlink_skb_parms *req); | ||
| 70 | 68 | ||
| 71 | extern int ip6_rt_addr_add(struct in6_addr *addr, | 69 | extern int ip6_rt_addr_add(struct in6_addr *addr, |
| 72 | struct net_device *dev, | 70 | struct net_device *dev, |
| @@ -114,6 +112,7 @@ extern int rt6_route_rcv(struct net_device *dev, · 41 unmodified lines | |||
| 114 | struct in6_addr *gwaddr); | 112 | struct in6_addr *gwaddr); |
| 115 | 113 | ||
| 116 | extern void rt6_redirect(struct in6_addr *dest, | 114 | extern void rt6_redirect(struct in6_addr *dest, |
| 115 | struct in6_addr *src, | ||
| 117 | struct in6_addr *saddr, | 116 | struct in6_addr *saddr, |
| 118 | struct neighbour *neigh, | 117 | struct neighbour *neigh, |
| 119 | u8 *lladdr, | 118 | u8 *lladdr, |
| @@ -131,6 +130,13 @@ extern int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a · 11 unmodified lines | |||
| 131 | extern int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | 130 | extern int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); |
| 132 | extern int inet6_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | 131 | extern int inet6_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); |
| 133 | 132 | ||
| 133 | struct rt6_rtnl_dump_arg | ||
| 134 | { | ||
| 135 | struct sk_buff *skb; | ||
| 136 | struct netlink_callback *cb; | ||
| 137 | }; | ||
| 138 | |||
| 139 | extern int rt6_dump_route(struct rt6_info *rt, void *p_arg); | ||
| 134 | extern void rt6_ifdown(struct net_device *dev); | 140 | extern void rt6_ifdown(struct net_device *dev); |
| 135 | extern void rt6_mtu_change(struct net_device *dev, unsigned mtu); | 141 | extern void rt6_mtu_change(struct net_device *dev, unsigned mtu); |
| 136 | 142 | ||
| @@ -140,21 +146,24 @@ extern rwlock_t rt6_lock; · 3 unmodified lines | |||
| 140 | * Store a destination cache entry in a socket | 146 | * Store a destination cache entry in a socket |
| 141 | */ | 147 | */ |
| 142 | static inline void __ip6_dst_store(struct sock *sk, struct dst_entry *dst, | 148 | static inline void __ip6_dst_store(struct sock *sk, struct dst_entry *dst, |
| 143 | struct in6_addr *daddr) | 149 | struct in6_addr *daddr, struct in6_addr *saddr) |
| 144 | { | 150 | { |
| 145 | struct ipv6_pinfo *np = inet6_sk(sk); | 151 | struct ipv6_pinfo *np = inet6_sk(sk); |
| 146 | struct rt6_info *rt = (struct rt6_info *) dst; | 152 | struct rt6_info *rt = (struct rt6_info *) dst; |
| 147 | 153 | ||
| 148 | sk_setup_caps(sk, dst); | 154 | sk_setup_caps(sk, dst); |
| 149 | np->daddr_cache = daddr; | 155 | np->daddr_cache = daddr; |
| 156 | #ifdef CONFIG_IPV6_SUBTREES | ||
| 157 | np->saddr_cache = saddr; | ||
| 158 | #endif | ||
| 150 | np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; | 159 | np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; |
| 151 | } | 160 | } |
| 152 | 161 | ||
| 153 | static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst, | 162 | static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst, |
| 154 | struct in6_addr *daddr) | 163 | struct in6_addr *daddr, struct in6_addr *saddr) |
| 155 | { | 164 | { |
| 156 | write_lock(&sk->sk_dst_lock); | 165 | write_lock(&sk->sk_dst_lock); |
| 157 | __ip6_dst_store(sk, dst, daddr); | 166 | __ip6_dst_store(sk, dst, daddr, saddr); |
| 158 | write_unlock(&sk->sk_dst_lock); | 167 | write_unlock(&sk->sk_dst_lock); |
| 159 | } | 168 | } |
| 160 | 169 | ||
| @@ -18,26 +18,34 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #include <net/flow.h> | 19 | #include <net/flow.h> |
| 20 | #include <linux/seq_file.h> | 20 | #include <linux/seq_file.h> |
| 21 | 21 | #include <net/fib_rules.h> | |
| 22 | /* WARNING: The ordering of these elements must match ordering | 22 | |
| 23 | * of RTA_* rtnetlink attribute numbers. | 23 | struct fib_config { |
| 24 | */ | 24 | u8 fc_family; |
| 25 | struct kern_rta { | 25 | u8 fc_dst_len; |
| 26 | void *rta_dst; | 26 | u8 fc_src_len; |
| 27 | void *rta_src; | 27 | u8 fc_tos; |
| 28 | int *rta_iif; | 28 | u8 fc_protocol; |
| 29 | int *rta_oif; | 29 | u8 fc_scope; |
| 30 | void *rta_gw; | 30 | u8 fc_type; |
| 31 | u32 *rta_priority; | 31 | /* 1 byte unused */ |
| 32 | void *rta_prefsrc; | 32 | u32 fc_table; |
| 33 | struct rtattr *rta_mx; | 33 | u32 fc_dst; |
| 34 | struct rtattr *rta_mp; | 34 | u32 fc_src; |
| 35 | unsigned char *rta_protoinfo; | 35 | u32 fc_gw; |
| 36 | u32 *rta_flow; | 36 | int fc_oif; |
| 37 | struct rta_cacheinfo *rta_ci; | 37 | u32 fc_flags; |
| 38 | struct rta_session *rta_sess; | 38 | u32 fc_priority; |
| 39 | u32 *rta_mp_alg; | 39 | u32 fc_prefsrc; |
| 40 | }; | 40 | struct nlattr *fc_mx; |
| 41 | struct rtnexthop *fc_mp; | ||
| 42 | int fc_mx_len; | ||
| 43 | int fc_mp_len; | ||
| 44 | u32 fc_flow; | ||
| 45 | u32 fc_mp_alg; | ||
| 46 | u32 fc_nlflags; | ||
| 47 | struct nl_info fc_nlinfo; | ||
| 48 | }; | ||
| 41 | 49 | ||
| 42 | struct fib_info; | 50 | struct fib_info; |
| 43 | 51 | ||
| @@ -149,15 +157,12 @@ struct fib_result_nl { · 105 unmodified lines | |||
| 149 | #endif /* CONFIG_IP_ROUTE_MULTIPATH_WRANDOM */ | 157 | #endif /* CONFIG_IP_ROUTE_MULTIPATH_WRANDOM */ |
| 150 | 158 | ||
| 151 | struct fib_table { | 159 | struct fib_table { |
| 152 | unsigned char tb_id; | 160 | struct hlist_node tb_hlist; |
| 161 | u32 tb_id; | ||
| 153 | unsigned tb_stamp; | 162 | unsigned tb_stamp; |
| 154 | int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res); | 163 | int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res); |
| 155 | int (*tb_insert)(struct fib_table *table, struct rtmsg *r, | 164 | int (*tb_insert)(struct fib_table *, struct fib_config *); |
| 156 | struct kern_rta *rta, struct nlmsghdr *n, | 165 | int (*tb_delete)(struct fib_table *, struct fib_config *); |
| 157 | struct netlink_skb_parms *req); | ||
| 158 | int (*tb_delete)(struct fib_table *table, struct rtmsg *r, | ||
| 159 | struct kern_rta *rta, struct nlmsghdr *n, | ||
| 160 | struct netlink_skb_parms *req); | ||
| 161 | int (*tb_dump)(struct fib_table *table, struct sk_buff *skb, | 166 | int (*tb_dump)(struct fib_table *table, struct sk_buff *skb, |
| 162 | struct netlink_callback *cb); | 167 | struct netlink_callback *cb); |
| 163 | int (*tb_flush)(struct fib_table *table); | 168 | int (*tb_flush)(struct fib_table *table); |
| @@ -172,14 +177,14 @@ struct fib_table { · 8 unmodified lines | |||
| 172 | extern struct fib_table *ip_fib_local_table; | 177 | extern struct fib_table *ip_fib_local_table; |
| 173 | extern struct fib_table *ip_fib_main_table; | 178 | extern struct fib_table *ip_fib_main_table; |
| 174 | 179 | ||
| 175 | static inline struct fib_table *fib_get_table(int id) | 180 | static inline struct fib_table *fib_get_table(u32 id) |
| 176 | { | 181 | { |
| 177 | if (id != RT_TABLE_LOCAL) | 182 | if (id != RT_TABLE_LOCAL) |
| 178 | return ip_fib_main_table; | 183 | return ip_fib_main_table; |
| 179 | return ip_fib_local_table; | 184 | return ip_fib_local_table; |
| 180 | } | 185 | } |
| 181 | 186 | ||
| 182 | static inline struct fib_table *fib_new_table(int id) | 187 | static inline struct fib_table *fib_new_table(u32 id) |
| 183 | { | 188 | { |
| 184 | return fib_get_table(id); | 189 | return fib_get_table(id); |
| 185 | } | 190 | } |
| @@ -199,35 +204,19 @@ static inline void fib_select_default(const struct flowi *flp, struct fib_result · 13 unmodified lines | |||
| 199 | } | 204 | } |
| 200 | 205 | ||
| 201 | #else /* CONFIG_IP_MULTIPLE_TABLES */ | 206 | #else /* CONFIG_IP_MULTIPLE_TABLES */ |
| 202 | #define ip_fib_local_table (fib_tables[RT_TABLE_LOCAL]) | 207 | #define ip_fib_local_table fib_get_table(RT_TABLE_LOCAL) |
| 203 | #define ip_fib_main_table (fib_tables[RT_TABLE_MAIN]) | 208 | #define ip_fib_main_table fib_get_table(RT_TABLE_MAIN) |
| 204 | |||
| 205 | extern struct fib_table * fib_tables[RT_TABLE_MAX+1]; | ||
| 206 | extern int fib_lookup(const struct flowi *flp, struct fib_result *res); | ||
| 207 | extern struct fib_table *__fib_new_table(int id); | ||
| 208 | extern void fib_rule_put(struct fib_rule *r); | ||
| 209 | 209 | ||
| 210 | static inline struct fib_table *fib_get_table(int id) | 210 | extern int fib_lookup(struct flowi *flp, struct fib_result *res); |
| 211 | { | ||
| 212 | if (id == 0) | ||
| 213 | id = RT_TABLE_MAIN; | ||
| 214 | |||
| 215 | return fib_tables[id]; | ||
| 216 | } | ||
| 217 | |||
| 218 | static inline struct fib_table *fib_new_table(int id) | ||
| 219 | { | ||
| 220 | if (id == 0) | ||
| 221 | id = RT_TABLE_MAIN; | ||
| 222 | |||
| 223 | return fib_tables[id] ? : __fib_new_table(id); | ||
| 224 | } | ||
| 225 | 211 | ||
| 212 | extern struct fib_table *fib_new_table(u32 id); | ||
| 213 | extern struct fib_table *fib_get_table(u32 id); | ||
| 226 | extern void fib_select_default(const struct flowi *flp, struct fib_result *res); | 214 | extern void fib_select_default(const struct flowi *flp, struct fib_result *res); |
| 227 | 215 | ||
| 228 | #endif /* CONFIG_IP_MULTIPLE_TABLES */ | 216 | #endif /* CONFIG_IP_MULTIPLE_TABLES */ |
| 229 | 217 | ||
| 230 | /* Exported by fib_frontend.c */ | 218 | /* Exported by fib_frontend.c */ |
| 219 | extern struct nla_policy rtm_ipv4_policy[]; | ||
| 231 | extern void ip_fib_init(void); | 220 | extern void ip_fib_init(void); |
| 232 | extern int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | 221 | extern int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); |
| 233 | extern int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | 222 | extern int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); |
| @@ -243,23 +232,20 @@ struct rtentry; · 9 unmodified lines | |||
| 243 | extern int ip_fib_check_default(u32 gw, struct net_device *dev); | 232 | extern int ip_fib_check_default(u32 gw, struct net_device *dev); |
| 244 | extern int fib_sync_down(u32 local, struct net_device *dev, int force); | 233 | extern int fib_sync_down(u32 local, struct net_device *dev, int force); |
| 245 | extern int fib_sync_up(struct net_device *dev); | 234 | extern int fib_sync_up(struct net_device *dev); |
| 246 | extern int fib_convert_rtentry(int cmd, struct nlmsghdr *nl, struct rtmsg *rtm, | ||
| 247 | struct kern_rta *rta, struct rtentry *r); | ||
| 248 | extern u32 __fib_res_prefsrc(struct fib_result *res); | 235 | extern u32 __fib_res_prefsrc(struct fib_result *res); |
| 249 | 236 | ||
| 250 | /* Exported by fib_hash.c */ | 237 | /* Exported by fib_hash.c */ |
| 251 | extern struct fib_table *fib_hash_init(int id); | 238 | extern struct fib_table *fib_hash_init(u32 id); |
| 252 | 239 | ||
| 253 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 240 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
| 254 | /* Exported by fib_rules.c */ | 241 | extern int fib4_rules_dump(struct sk_buff *skb, struct netlink_callback *cb); |
| 242 | |||
| 243 | extern void __init fib4_rules_init(void); | ||
| 255 | 244 | ||
| 256 | extern int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | ||
| 257 | extern int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | ||
| 258 | extern int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb); | ||
| 259 | #ifdef CONFIG_NET_CLS_ROUTE | 245 | #ifdef CONFIG_NET_CLS_ROUTE |
| 260 | extern u32 fib_rules_tclass(struct fib_result *res); | 246 | extern u32 fib_rules_tclass(struct fib_result *res); |
| 261 | #endif | 247 | #endif |
| 262 | extern void fib_rules_init(void); | 248 | |
| 263 | #endif | 249 | #endif |
| 264 | 250 | ||
| 265 | static inline void fib_combine_itag(u32 *itag, struct fib_result *res) | 251 | static inline void fib_combine_itag(u32 *itag, struct fib_result *res) |
| @@ -40,6 +40,7 @@ · 39 unmodified lines | |||
| 40 | #define NEXTHDR_ICMP 58 /* ICMP for IPv6. */ | 40 | #define NEXTHDR_ICMP 58 /* ICMP for IPv6. */ |
| 41 | #define NEXTHDR_NONE 59 /* No next header */ | 41 | #define NEXTHDR_NONE 59 /* No next header */ |
| 42 | #define NEXTHDR_DEST 60 /* Destination options header. */ | 42 | #define NEXTHDR_DEST 60 /* Destination options header. */ |
| 43 | #define NEXTHDR_MOBILITY 135 /* Mobility header. */ | ||
| 43 | 44 | ||
| 44 | #define NEXTHDR_MAX 255 | 45 | #define NEXTHDR_MAX 255 |
| 45 | 46 | ||
| @@ -229,7 +230,7 @@ extern int ip6_ra_control(struct sock *sk, int sel, · 183 unmodified lines | |||
| 229 | void (*destructor)(struct sock *)); | 230 | void (*destructor)(struct sock *)); |
| 230 | 231 | ||
| 231 | 232 | ||
| 232 | extern int ipv6_parse_hopopts(struct sk_buff *skb); | 233 | extern int ipv6_parse_hopopts(struct sk_buff **skbp); |
| 233 | 234 | ||
| 234 | extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt); | 235 | extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt); |
| 235 | extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, | 236 | extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, |
| @@ -506,6 +507,8 @@ extern int ipv6_skip_exthdr(const struct sk_buff *, int start, · 270 unmodified lines | |||
| 506 | 507 | ||
| 507 | extern int ipv6_ext_hdr(u8 nexthdr); | 508 | extern int ipv6_ext_hdr(u8 nexthdr); |
| 508 | 509 | ||
| 510 | extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type); | ||
| 511 | |||
| 509 | extern struct ipv6_txoptions * ipv6_invert_rthdr(struct sock *sk, | 512 | extern struct ipv6_txoptions * ipv6_invert_rthdr(struct sock *sk, |
| 510 | struct ipv6_rt_hdr *hdr); | 513 | struct ipv6_rt_hdr *hdr); |
| 511 | 514 | ||
| @@ -0,0 +1,61 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C)2003-2006 Helsinki University of Technology | ||
| 3 | * Copyright (C)2003-2006 USAGI/WIDE Project | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | */ | ||
| 19 | /* | ||
| 20 | * Authors: | ||
| 21 | * Noriaki TAKAMIYA @USAGI | ||
| 22 | * Masahide NAKAMURA @USAGI | ||
| 23 | * YOSHIFUJI Hideaki @USAGI | ||
| 24 | */ | ||
| 25 | #ifndef _NET_MIP6_H | ||
| 26 | #define _NET_MIP6_H | ||
| 27 | |||
| 28 | #include <linux/skbuff.h> | ||
| 29 | #include <net/sock.h> | ||
| 30 | |||
| 31 | #define MIP6_OPT_PAD_1 0 | ||
| 32 | #define MIP6_OPT_PAD_N 1 | ||
| 33 | |||
| 34 | /* | ||
| 35 | * Mobility Header | ||
| 36 | */ | ||
| 37 | struct ip6_mh { | ||
| 38 | __u8 ip6mh_proto; | ||
| 39 | __u8 ip6mh_hdrlen; | ||
| 40 | __u8 ip6mh_type; | ||
| 41 | __u8 ip6mh_reserved; | ||
| 42 | __u16 ip6mh_cksum; | ||
| 43 | /* Followed by type specific messages */ | ||
| 44 | __u8 data[0]; | ||
| 45 | } __attribute__ ((__packed__)); | ||
| 46 | |||
| 47 | #define IP6_MH_TYPE_BRR 0 /* Binding Refresh Request */ | ||
| 48 | #define IP6_MH_TYPE_HOTI 1 /* HOTI Message */ | ||
| 49 | #define IP6_MH_TYPE_COTI 2 /* COTI Message */ | ||
| 50 | #define IP6_MH_TYPE_HOT 3 /* HOT Message */ | ||
| 51 | #define IP6_MH_TYPE_COT 4 /* COT Message */ | ||
| 52 | #define IP6_MH_TYPE_BU 5 /* Binding Update */ | ||
| 53 | #define IP6_MH_TYPE_BACK 6 /* Binding ACK */ | ||
| 54 | #define IP6_MH_TYPE_BERROR 7 /* Binding Error */ | ||
| 55 | #define IP6_MH_TYPE_MAX IP6_MH_TYPE_BERROR | ||
| 56 | |||
| 57 | extern int mip6_init(void); | ||
| 58 | extern void mip6_fini(void); | ||
| 59 | extern int mip6_mh_filter(struct sock *sk, struct sk_buff *skb); | ||
| 60 | |||
| 61 | #endif | ||
| @@ -1,6 +1,8 @@ | |||
| 1 | #ifndef _NET_NEIGHBOUR_H | 1 | #ifndef _NET_NEIGHBOUR_H |
| 2 | #define _NET_NEIGHBOUR_H | 2 | #define _NET_NEIGHBOUR_H |
| 3 | 3 | ||
| 4 | #include <linux/neighbour.h> | ||
| 5 | |||
| 4 | /* | 6 | /* |
| 5 | * Generic neighbour manipulation | 7 | * Generic neighbour manipulation |
| 6 | * | 8 | * |
| @@ -14,40 +16,6 @@ · 7 unmodified lines | |||
| 14 | * - Add neighbour cache statistics like rtstat | 16 | * - Add neighbour cache statistics like rtstat |
| 15 | */ | 17 | */ |
| 16 | 18 | ||
| 17 | /* The following flags & states are exported to user space, | ||
| 18 | so that they should be moved to include/linux/ directory. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * Neighbor Cache Entry Flags | ||
| 23 | */ | ||
| 24 | |||
| 25 | #define NTF_PROXY 0x08 /* == ATF_PUBL */ | ||
| 26 | #define NTF_ROUTER 0x80 | ||
| 27 | |||
| 28 | /* | ||
| 29 | * Neighbor Cache Entry States. | ||
| 30 | */ | ||
| 31 | |||
| 32 | #define NUD_INCOMPLETE 0x01 | ||
| 33 | #define NUD_REACHABLE 0x02 | ||
| 34 | #define NUD_STALE 0x04 | ||
| 35 | #define NUD_DELAY 0x08 | ||
| 36 | #define NUD_PROBE 0x10 | ||
| 37 | #define NUD_FAILED 0x20 | ||
| 38 | |||
| 39 | /* Dummy states */ | ||
| 40 | #define NUD_NOARP 0x40 | ||
| 41 | #define NUD_PERMANENT 0x80 | ||
| 42 | #define NUD_NONE 0x00 | ||
| 43 | |||
| 44 | /* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change | ||
| 45 | and make no address resolution or NUD. | ||
| 46 | NUD_PERMANENT is also cannot be deleted by garbage collectors. | ||
| 47 | */ | ||
| 48 | |||
| 49 | #ifdef __KERNEL__ | ||
| 50 | |||
| 51 | #include <asm/atomic.h> | 19 | #include <asm/atomic.h> |
| 52 | #include <linux/netdevice.h> | 20 | #include <linux/netdevice.h> |
| 53 | #include <linux/skbuff.h> | 21 | #include <linux/skbuff.h> |
| @@ -133,7 +101,7 @@ struct neighbour · 79 unmodified lines | |||
| 133 | __u8 dead; | 101 | __u8 dead; |
| 134 | atomic_t probes; | 102 | atomic_t probes; |
| 135 | rwlock_t lock; | 103 | rwlock_t lock; |
| 136 | unsigned char ha[(MAX_ADDR_LEN+sizeof(unsigned long)-1)&~(sizeof(unsigned long)-1)]; | 104 | unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; |
| 137 | struct hh_cache *hh; | 105 | struct hh_cache *hh; |
| 138 | atomic_t refcnt; | 106 | atomic_t refcnt; |
| 139 | int (*output)(struct sk_buff *skb); | 107 | int (*output)(struct sk_buff *skb); |
| @@ -158,6 +126,7 @@ struct pneigh_entry · 18 unmodified lines | |||
| 158 | { | 126 | { |
| 159 | struct pneigh_entry *next; | 127 | struct pneigh_entry *next; |
| 160 | struct net_device *dev; | 128 | struct net_device *dev; |
| 129 | u8 flags; | ||
| 161 | u8 key[0]; | 130 | u8 key[0]; |
| 162 | }; | 131 | }; |
| 163 | 132 | ||
| @@ -374,6 +343,3 @@ struct neighbour_cb { · 210 unmodified lines | |||
| 374 | #define NEIGH_CB(skb) ((struct neighbour_cb *)(skb)->cb) | 343 | #define NEIGH_CB(skb) ((struct neighbour_cb *)(skb)->cb) |
| 375 | 344 | ||
| 376 | #endif | 345 | #endif |
| 377 | #endif | ||
| 378 | |||
| 379 | |||
| @@ -0,0 +1,292 @@ | |||
| 1 | /* | ||
| 2 | * NetLabel System | ||
| 3 | * | ||
| 4 | * The NetLabel system manages static and dynamic label mappings for network | ||
| 5 | * protocols such as CIPSO and RIPSO. | ||
| 6 | * | ||
| 7 | * Author: Paul Moore <paul.moore@hp.com> | ||
| 8 | * | ||
| 9 | */ | ||
| 10 | |||
| 11 | /* | ||
| 12 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 | ||
| 13 | * | ||
| 14 | * This program is free software; you can redistribute it and/or modify | ||
| 15 | * it under the terms of the GNU General Public License as published by | ||
| 16 | * the Free Software Foundation; either version 2 of the License, or | ||
| 17 | * (at your option) any later version. | ||
| 18 | * | ||
| 19 | * This program is distributed in the hope that it will be useful, | ||
| 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
| 22 | * the GNU General Public License for more details. | ||
| 23 | * | ||
| 24 | * You should have received a copy of the GNU General Public License | ||
| 25 | * along with this program; if not, write to the Free Software | ||
| 26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 27 | * | ||
| 28 | */ | ||
| 29 | |||
| 30 | #ifndef _NETLABEL_H | ||
| 31 | #define _NETLABEL_H | ||
| 32 | |||
| 33 | #include <linux/types.h> | ||
| 34 | #include <linux/net.h> | ||
| 35 | #include <linux/skbuff.h> | ||
| 36 | #include <net/netlink.h> | ||
| 37 | |||
| 38 | /* | ||
| 39 | * NetLabel - A management interface for maintaining network packet label | ||
| 40 | * mapping tables for explicit packet labling protocols. | ||
| 41 | * | ||
| 42 | * Network protocols such as CIPSO and RIPSO require a label translation layer | ||
| 43 | * to convert the label on the packet into something meaningful on the host | ||
| 44 | * machine. In the current Linux implementation these mapping tables live | ||
| 45 | * inside the kernel; NetLabel provides a mechanism for user space applications | ||
| 46 | * to manage these mapping tables. | ||
| 47 | * | ||
| 48 | * NetLabel makes use of the Generic NETLINK mechanism as a transport layer to | ||
| 49 | * send messages between kernel and user space. The general format of a | ||
| 50 | * NetLabel message is shown below: | ||
| 51 | * | ||
| 52 | * +-----------------+-------------------+--------- --- -- - | ||
| 53 | * | struct nlmsghdr | struct genlmsghdr | payload | ||
| 54 | * +-----------------+-------------------+--------- --- -- - | ||
| 55 | * | ||
| 56 | * The 'nlmsghdr' and 'genlmsghdr' structs should be dealt with like normal. | ||
| 57 | * The payload is dependent on the subsystem specified in the | ||
| 58 | * 'nlmsghdr->nlmsg_type' and should be defined below, supporting functions | ||
| 59 | * should be defined in the corresponding net/netlabel/netlabel_<subsys>.h|c | ||
| 60 | * file. All of the fields in the NetLabel payload are NETLINK attributes, the | ||
| 61 | * length of each field is the length of the NETLINK attribute payload, see | ||
| 62 | * include/net/netlink.h for more information on NETLINK attributes. | ||
| 63 | * | ||
| 64 | */ | ||
| 65 | |||
| 66 | /* | ||
| 67 | * NetLabel NETLINK protocol | ||
| 68 | */ | ||
| 69 | |||
| 70 | #define NETLBL_PROTO_VERSION 1 | ||
| 71 | |||
| 72 | /* NetLabel NETLINK types/families */ | ||
| 73 | #define NETLBL_NLTYPE_NONE 0 | ||
| 74 | #define NETLBL_NLTYPE_MGMT 1 | ||
| 75 | #define NETLBL_NLTYPE_MGMT_NAME "NLBL_MGMT" | ||
| 76 | #define NETLBL_NLTYPE_RIPSO 2 | ||
| 77 | #define NETLBL_NLTYPE_RIPSO_NAME "NLBL_RIPSO" | ||
| 78 | #define NETLBL_NLTYPE_CIPSOV4 3 | ||
| 79 | #define NETLBL_NLTYPE_CIPSOV4_NAME "NLBL_CIPSOv4" | ||
| 80 | #define NETLBL_NLTYPE_CIPSOV6 4 | ||
| 81 | #define NETLBL_NLTYPE_CIPSOV6_NAME "NLBL_CIPSOv6" | ||
| 82 | #define NETLBL_NLTYPE_UNLABELED 5 | ||
| 83 | #define NETLBL_NLTYPE_UNLABELED_NAME "NLBL_UNLBL" | ||
| 84 | |||
| 85 | /* NetLabel return codes */ | ||
| 86 | #define NETLBL_E_OK 0 | ||
| 87 | |||
| 88 | /* | ||
| 89 | * Helper functions | ||
| 90 | */ | ||
| 91 | |||
| 92 | #define NETLBL_LEN_U8 nla_total_size(sizeof(u8)) | ||
| 93 | #define NETLBL_LEN_U16 nla_total_size(sizeof(u16)) | ||
| 94 | #define NETLBL_LEN_U32 nla_total_size(sizeof(u32)) | ||
| 95 | |||
| 96 | /** | ||
| 97 | * netlbl_netlink_alloc_skb - Allocate a NETLINK message buffer | ||
| 98 | * @head: the amount of headroom in bytes | ||
| 99 | * @body: the desired size (minus headroom) in bytes | ||
| 100 | * @gfp_flags: the alloc flags to pass to alloc_skb() | ||
| 101 | * | ||
| 102 | * Description: | ||
| 103 | * Allocate a NETLINK message buffer based on the sizes given in @head and | ||
| 104 | * @body. If @head is greater than zero skb_reserve() is called to reserve | ||
| 105 | * @head bytes at the start of the buffer. Returns a valid sk_buff pointer on | ||
| 106 | * success, NULL on failure. | ||
| 107 | * | ||
| 108 | */ | ||
| 109 | static inline struct sk_buff *netlbl_netlink_alloc_skb(size_t head, | ||
| 110 | size_t body, | ||
| 111 | int gfp_flags) | ||
| 112 | { | ||
| 113 | struct sk_buff *skb; | ||
| 114 | |||
| 115 | skb = alloc_skb(NLMSG_ALIGN(head + body), gfp_flags); | ||
| 116 | if (skb == NULL) | ||
| 117 | return NULL; | ||
| 118 | if (head > 0) { | ||
| 119 | skb_reserve(skb, head); | ||
| 120 | if (skb_tailroom(skb) < body) { | ||
| 121 | kfree_skb(skb); | ||
| 122 | return NULL; | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | return skb; | ||
| 127 | } | ||
| 128 | |||
| 129 | /* | ||
| 130 | * NetLabel - Kernel API for accessing the network packet label mappings. | ||
| 131 | * | ||
| 132 | * The following functions are provided for use by other kernel modules, | ||
| 133 | * specifically kernel LSM modules, to provide a consistent, transparent API | ||
| 134 | * for dealing with explicit packet labeling protocols such as CIPSO and | ||
| 135 | * RIPSO. The functions defined here are implemented in the | ||
| 136 | * net/netlabel/netlabel_kapi.c file. | ||
| 137 | * | ||
| 138 | */ | ||
| 139 | |||
| 140 | /* Domain mapping definition struct */ | ||
| 141 | struct netlbl_dom_map; | ||
| 142 | |||
| 143 | /* Domain mapping operations */ | ||
| 144 | int netlbl_domhsh_remove(const char *domain); | ||
| 145 | |||
| 146 | /* LSM security attributes */ | ||
| 147 | struct netlbl_lsm_cache { | ||
| 148 | void (*free) (const void *data); | ||
| 149 | void *data; | ||
| 150 | }; | ||
| 151 | struct netlbl_lsm_secattr { | ||
| 152 | char *domain; | ||
| 153 | |||
| 154 | u32 mls_lvl; | ||
| 155 | u32 mls_lvl_vld; | ||
| 156 | unsigned char *mls_cat; | ||
| 157 | size_t mls_cat_len; | ||
| 158 | |||
| 159 | struct netlbl_lsm_cache cache; | ||
| 160 | }; | ||
| 161 | |||
| 162 | /* | ||
| 163 | * LSM security attribute operations | ||
| 164 | */ | ||
| 165 | |||
| 166 | |||
| 167 | /** | ||
| 168 | * netlbl_secattr_init - Initialize a netlbl_lsm_secattr struct | ||
| 169 | * @secattr: the struct to initialize | ||
| 170 | * | ||
| 171 | * Description: | ||
| 172 | * Initialize an already allocated netlbl_lsm_secattr struct. Returns zero on | ||
| 173 | * success, negative values on error. | ||
| 174 | * | ||
| 175 | */ | ||
| 176 | static inline int netlbl_secattr_init(struct netlbl_lsm_secattr *secattr) | ||
| 177 | { | ||
| 178 | memset(secattr, 0, sizeof(*secattr)); | ||
| 179 | return 0; | ||
| 180 | } | ||
| 181 | |||
| 182 | /** | ||
| 183 | * netlbl_secattr_destroy - Clears a netlbl_lsm_secattr struct | ||
| 184 | * @secattr: the struct to clear | ||
| 185 | * @clear_cache: cache clear flag | ||
| 186 | * | ||
| 187 | * Description: | ||
| 188 | * Destroys the @secattr struct, including freeing all of the internal buffers. | ||
| 189 | * If @clear_cache is true then free the cache fields, otherwise leave them | ||
| 190 | * intact. The struct must be reset with a call to netlbl_secattr_init() | ||
| 191 | * before reuse. | ||
| 192 | * | ||
| 193 | */ | ||
| 194 | static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr, | ||
| 195 | u32 clear_cache) | ||
| 196 | { | ||
| 197 | if (clear_cache && secattr->cache.data != NULL && secattr->cache.free) | ||
| 198 | secattr->cache.free(secattr->cache.data); | ||
| 199 | kfree(secattr->domain); | ||
| 200 | kfree(secattr->mls_cat); | ||
| 201 | } | ||
| 202 | |||
| 203 | /** | ||
| 204 | * netlbl_secattr_alloc - Allocate and initialize a netlbl_lsm_secattr struct | ||
| 205 | * @flags: the memory allocation flags | ||
| 206 | * | ||
| 207 | * Description: | ||
| 208 | * Allocate and initialize a netlbl_lsm_secattr struct. Returns a valid | ||
| 209 | * pointer on success, or NULL on failure. | ||
| 210 | * | ||
| 211 | */ | ||
| 212 | static inline struct netlbl_lsm_secattr *netlbl_secattr_alloc(int flags) | ||
| 213 | { | ||
| 214 | return kzalloc(sizeof(struct netlbl_lsm_secattr), flags); | ||
| 215 | } | ||
| 216 | |||
| 217 | /** | ||
| 218 | * netlbl_secattr_free - Frees a netlbl_lsm_secattr struct | ||
| 219 | * @secattr: the struct to free | ||
| 220 | * @clear_cache: cache clear flag | ||
| 221 | * | ||
| 222 | * Description: | ||
| 223 | * Frees @secattr including all of the internal buffers. If @clear_cache is | ||
| 224 | * true then free the cache fields, otherwise leave them intact. | ||
| 225 | * | ||
| 226 | */ | ||
| 227 | static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr, | ||
| 228 | u32 clear_cache) | ||
| 229 | { | ||
| 230 | netlbl_secattr_destroy(secattr, clear_cache); | ||
| 231 | kfree(secattr); | ||
| 232 | } | ||
| 233 | |||
| 234 | /* | ||
| 235 | * LSM protocol operations | ||
| 236 | */ | ||
| 237 | |||
| 238 | #ifdef CONFIG_NETLABEL | ||
| 239 | int netlbl_socket_setattr(const struct socket *sock, | ||
| 240 | const struct netlbl_lsm_secattr *secattr); | ||
| 241 | int netlbl_socket_getattr(const struct socket *sock, | ||
| 242 | struct netlbl_lsm_secattr *secattr); | ||
| 243 | int netlbl_skbuff_getattr(const struct sk_buff *skb, | ||
| 244 | struct netlbl_lsm_secattr *secattr); | ||
| 245 | void netlbl_skbuff_err(struct sk_buff *skb, int error); | ||
| 246 | #else | ||
| 247 | static inline int netlbl_socket_setattr(const struct socket *sock, | ||
| 248 | const struct netlbl_lsm_secattr *secattr) | ||
| 249 | { | ||
| 250 | return -ENOSYS; | ||
| 251 | } | ||
| 252 | |||
| 253 | static inline int netlbl_socket_getattr(const struct socket *sock, | ||
| 254 | struct netlbl_lsm_secattr *secattr) | ||
| 255 | { | ||
| 256 | return -ENOSYS; | ||
| 257 | } | ||
| 258 | |||
| 259 | static inline int netlbl_skbuff_getattr(const struct sk_buff *skb, | ||
| 260 | struct netlbl_lsm_secattr *secattr) | ||
| 261 | { | ||
| 262 | return -ENOSYS; | ||
| 263 | } | ||
| 264 | |||
| 265 | static inline void netlbl_skbuff_err(struct sk_buff *skb, int error) | ||
| 266 | { | ||
| 267 | return; | ||
| 268 | } | ||
| 269 | #endif /* CONFIG_NETLABEL */ | ||
| 270 | |||
| 271 | /* | ||
| 272 | * LSM label mapping cache operations | ||
| 273 | */ | ||
| 274 | |||
| 275 | #ifdef CONFIG_NETLABEL | ||
| 276 | void netlbl_cache_invalidate(void); | ||
| 277 | int netlbl_cache_add(const struct sk_buff *skb, | ||
| 278 | const struct netlbl_lsm_secattr *secattr); | ||
| 279 | #else | ||
| 280 | static inline void netlbl_cache_invalidate(void) | ||
| 281 | { | ||
| 282 | return; | ||
| 283 | } | ||
| 284 | |||
| 285 | static inline int netlbl_cache_add(const struct sk_buff *skb, | ||
| 286 | const struct netlbl_lsm_secattr *secattr) | ||
| 287 | { | ||
| 288 | return 0; | ||
| 289 | } | ||
| 290 | #endif /* CONFIG_NETLABEL */ | ||
| 291 | |||
| 292 | #endif /* _NETLABEL_H */ | ||
| @@ -35,12 +35,15 @@ · 34 unmodified lines | |||
| 35 | * nlmsg_put() add a netlink message to an skb | 35 | * nlmsg_put() add a netlink message to an skb |
| 36 | * nlmsg_put_answer() callback based nlmsg_put() | 36 | * nlmsg_put_answer() callback based nlmsg_put() |
| 37 | * nlmsg_end() finanlize netlink message | 37 | * nlmsg_end() finanlize netlink message |
| 38 | * nlmsg_get_pos() return current position in message | ||
| 39 | * nlmsg_trim() trim part of message | ||
| 38 | * nlmsg_cancel() cancel message construction | 40 | * nlmsg_cancel() cancel message construction |
| 39 | * nlmsg_free() free a netlink message | 41 | * nlmsg_free() free a netlink message |
| 40 | * | 42 | * |
| 41 | * Message Sending: | 43 | * Message Sending: |
| 42 | * nlmsg_multicast() multicast message to several groups | 44 | * nlmsg_multicast() multicast message to several groups |
| 43 | * nlmsg_unicast() unicast a message to a single socket | 45 | * nlmsg_unicast() unicast a message to a single socket |
| 46 | * nlmsg_notify() send notification message | ||
| 44 | * | 47 | * |
| 45 | * Message Length Calculations: | 48 | * Message Length Calculations: |
| 46 | * nlmsg_msg_size(payload) length of message w/o padding | 49 | * nlmsg_msg_size(payload) length of message w/o padding |
| @@ -62,6 +65,9 @@ · 15 unmodified lines | |||
| 62 | * nlmsg_validate() validate netlink message incl. attrs | 65 | * nlmsg_validate() validate netlink message incl. attrs |
| 63 | * nlmsg_for_each_attr() loop over all attributes | 66 | * nlmsg_for_each_attr() loop over all attributes |
| 64 | * | 67 | * |
| 68 | * Misc: | ||
| 69 | * nlmsg_report() report back to application? | ||
| 70 | * | ||
| 65 | * ------------------------------------------------------------------------ | 71 | * ------------------------------------------------------------------------ |
| 66 | * Attributes Interface | 72 | * Attributes Interface |
| 67 | * ------------------------------------------------------------------------ | 73 | * ------------------------------------------------------------------------ |
| @@ -80,8 +86,10 @@ · 12 unmodified lines | |||
| 80 | * struct nlattr netlink attribtue header | 86 | * struct nlattr netlink attribtue header |
| 81 | * | 87 | * |
| 82 | * Attribute Construction: | 88 | * Attribute Construction: |
| 83 | * nla_reserve(skb, type, len) reserve skb tailroom for an attribute | 89 | * nla_reserve(skb, type, len) reserve room for an attribute |
| 90 | * nla_reserve_nohdr(skb, len) reserve room for an attribute w/o hdr | ||
| 84 | * nla_put(skb, type, len, data) add attribute to skb | 91 | * nla_put(skb, type, len, data) add attribute to skb |
| 92 | * nla_put_nohdr(skb, len, data) add attribute w/o hdr | ||
| 85 | * | 93 | * |
| 86 | * Attribute Construction for Basic Types: | 94 | * Attribute Construction for Basic Types: |
| 87 | * nla_put_u8(skb, type, value) add u8 attribute to skb | 95 | * nla_put_u8(skb, type, value) add u8 attribute to skb |
| @@ -139,6 +147,7 @@ · 51 unmodified lines | |||
| 139 | * nla_next(nla, remaining) get next netlink attribute | 147 | * nla_next(nla, remaining) get next netlink attribute |
| 140 | * nla_validate() validate a stream of attributes | 148 | * nla_validate() validate a stream of attributes |
| 141 | * nla_find() find attribute in stream of attributes | 149 | * nla_find() find attribute in stream of attributes |
| 150 | * nla_find_nested() find attribute in nested attributes | ||
| 142 | * nla_parse() parse and validate stream of attrs | 151 | * nla_parse() parse and validate stream of attrs |
| 143 | * nla_parse_nested() parse nested attribuets | 152 | * nla_parse_nested() parse nested attribuets |
| 144 | * nla_for_each_attr() loop over all attributes | 153 | * nla_for_each_attr() loop over all attributes |
| @@ -158,6 +167,7 @@ enum { · 13 unmodified lines | |||
| 158 | NLA_FLAG, | 167 | NLA_FLAG, |
| 159 | NLA_MSECS, | 168 | NLA_MSECS, |
| 160 | NLA_NESTED, | 169 | NLA_NESTED, |
| 170 | NLA_NUL_STRING, | ||
| 161 | __NLA_TYPE_MAX, | 171 | __NLA_TYPE_MAX, |
| 162 | }; | 172 | }; |
| 163 | 173 | ||
| @@ -166,21 +176,37 @@ enum { · 2 unmodified lines | |||
| 166 | /** | 176 | /** |
| 167 | * struct nla_policy - attribute validation policy | 177 | * struct nla_policy - attribute validation policy |
| 168 | * @type: Type of attribute or NLA_UNSPEC | 178 | * @type: Type of attribute or NLA_UNSPEC |
| 169 | * @minlen: Minimal length of payload required to be available | 179 | * @len: Type specific length of payload |
| 170 | * | 180 | * |
| 171 | * Policies are defined as arrays of this struct, the array must be | 181 | * Policies are defined as arrays of this struct, the array must be |
| 172 | * accessible by attribute type up to the highest identifier to be expected. | 182 | * accessible by attribute type up to the highest identifier to be expected. |
| 173 | * | 183 | * |
| 184 | * Meaning of `len' field: | ||
| 185 | * NLA_STRING Maximum length of string | ||
| 186 | * NLA_NUL_STRING Maximum length of string (excluding NUL) | ||
| 187 | * NLA_FLAG Unused | ||
| 188 | * All other Exact length of attribute payload | ||
| 189 | * | ||
| 174 | * Example: | 190 | * Example: |
| 175 | * static struct nla_policy my_policy[ATTR_MAX+1] __read_mostly = { | 191 | * static struct nla_policy my_policy[ATTR_MAX+1] __read_mostly = { |
| 176 | * [ATTR_FOO] = { .type = NLA_U16 }, | 192 | * [ATTR_FOO] = { .type = NLA_U16 }, |
| 177 | * [ATTR_BAR] = { .type = NLA_STRING }, | 193 | * [ATTR_BAR] = { .type = NLA_STRING, len = BARSIZ }, |
| 178 | * [ATTR_BAZ] = { .minlen = sizeof(struct mystruct) }, | 194 | * [ATTR_BAZ] = { .len = sizeof(struct mystruct) }, |
| 179 | * }; | 195 | * }; |
| 180 | */ | 196 | */ |
| 181 | struct nla_policy { | 197 | struct nla_policy { |
| 182 | u16 type; | 198 | u16 type; |
| 183 | u16 minlen; | 199 | u16 len; |
| 200 | }; | ||
| 201 | |||
| 202 | /** | ||
| 203 | * struct nl_info - netlink source information | ||
| 204 | * @nlh: Netlink message header of original request | ||
| 205 | * @pid: Netlink PID of requesting application | ||
| 206 | */ | ||
| 207 | struct nl_info { | ||
| 208 | struct nlmsghdr *nlh; | ||
| 209 | u32 pid; | ||
| 184 | }; | 210 | }; |
| 185 | 211 | ||
| 186 | extern void netlink_run_queue(struct sock *sk, unsigned int *qlen, | 212 | extern void netlink_run_queue(struct sock *sk, unsigned int *qlen, |
| @@ -188,6 +214,9 @@ extern void netlink_run_queue(struct sock *sk, unsigned int *qlen, · 1 unmodified line | |||
| 188 | struct nlmsghdr *, int *)); | 214 | struct nlmsghdr *, int *)); |
| 189 | extern void netlink_queue_skip(struct nlmsghdr *nlh, | 215 | extern void netlink_queue_skip(struct nlmsghdr *nlh, |
| 190 | struct sk_buff *skb); | 216 | struct sk_buff *skb); |
| 217 | extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb, | ||
| 218 | u32 pid, unsigned int group, int report, | ||
| 219 | gfp_t flags); | ||
| 191 | 220 | ||
| 192 | extern int nla_validate(struct nlattr *head, int len, int maxtype, | 221 | extern int nla_validate(struct nlattr *head, int len, int maxtype, |
| 193 | struct nla_policy *policy); | 222 | struct nla_policy *policy); |
| @@ -203,12 +232,18 @@ extern int nla_memcmp(const struct nlattr *nla, const void *data, · 9 unmodified lines | |||
| 203 | extern int nla_strcmp(const struct nlattr *nla, const char *str); | 232 | extern int nla_strcmp(const struct nlattr *nla, const char *str); |
| 204 | extern struct nlattr * __nla_reserve(struct sk_buff *skb, int attrtype, | 233 | extern struct nlattr * __nla_reserve(struct sk_buff *skb, int attrtype, |
| 205 | int attrlen); | 234 | int attrlen); |
| 235 | extern void * __nla_reserve_nohdr(struct sk_buff *skb, int attrlen); | ||
| 206 | extern struct nlattr * nla_reserve(struct sk_buff *skb, int attrtype, | 236 | extern struct nlattr * nla_reserve(struct sk_buff *skb, int attrtype, |
| 207 | int attrlen); | 237 | int attrlen); |
| 238 | extern void * nla_reserve_nohdr(struct sk_buff *skb, int attrlen); | ||
| 208 | extern void __nla_put(struct sk_buff *skb, int attrtype, | 239 | extern void __nla_put(struct sk_buff *skb, int attrtype, |
| 209 | int attrlen, const void *data); | 240 | int attrlen, const void *data); |
| 241 | extern void __nla_put_nohdr(struct sk_buff *skb, int attrlen, | ||
| 242 | const void *data); | ||
| 210 | extern int nla_put(struct sk_buff *skb, int attrtype, | 243 | extern int nla_put(struct sk_buff *skb, int attrtype, |
| 211 | int attrlen, const void *data); | 244 | int attrlen, const void *data); |
| 245 | extern int nla_put_nohdr(struct sk_buff *skb, int attrlen, | ||
| 246 | const void *data); | ||
| 212 | 247 | ||
| 213 | /************************************************************************** | 248 | /************************************************************************** |
| 214 | * Netlink Messages | 249 | * Netlink Messages |
| @@ -363,6 +398,17 @@ static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype, · 148 unmodified lines | |||
| 363 | nlmsg_attrlen(nlh, hdrlen), maxtype, policy); | 398 | nlmsg_attrlen(nlh, hdrlen), maxtype, policy); |
| 364 | } | 399 | } |
| 365 | 400 | ||
| 401 | /** | ||
| 402 | * nlmsg_report - need to report back to application? | ||
| 403 | * @nlh: netlink message header | ||
| 404 | * | ||
| 405 | * Returns 1 if a report back to the application is requested. | ||
| 406 | */ | ||
| 407 | static inline int nlmsg_report(struct nlmsghdr *nlh) | ||
| 408 | { | ||
| 409 | return !!(nlh->nlmsg_flags & NLM_F_ECHO); | ||
| 410 | } | ||
| 411 | |||
| 366 | /** | 412 | /** |
| 367 | * nlmsg_for_each_attr - iterate over a stream of attributes | 413 | * nlmsg_for_each_attr - iterate over a stream of attributes |
| 368 | * @pos: loop counter, set to current attribute | 414 | * @pos: loop counter, set to current attribute |
| @@ -453,12 +499,13 @@ static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb, · 84 unmodified lines | |||
| 453 | /** | 499 | /** |
| 454 | * nlmsg_new - Allocate a new netlink message | 500 | * nlmsg_new - Allocate a new netlink message |
| 455 | * @size: maximum size of message | 501 | * @size: maximum size of message |
| 502 | * @flags: the type of memory to allocate. | ||
| 456 | * | 503 | * |
| 457 | * Use NLMSG_GOODSIZE if size isn't know and you need a good default size. | 504 | * Use NLMSG_GOODSIZE if size isn't know and you need a good default size. |
| 458 | */ | 505 | */ |
| 459 | static inline struct sk_buff *nlmsg_new(int size) | 506 | static inline struct sk_buff *nlmsg_new(int size, gfp_t flags) |
| 460 | { | 507 | { |
| 461 | return alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | 508 | return alloc_skb(size, flags); |
| 462 | } | 509 | } |
| 463 | 510 | ||
| 464 | /** | 511 | /** |
| @@ -479,6 +526,32 @@ static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh) · 14 unmodified lines | |||
| 479 | return skb->len; | 526 | return skb->len; |
| 480 | } | 527 | } |
| 481 | 528 | ||
| 529 | /** | ||
| 530 | * nlmsg_get_pos - return current position in netlink message | ||
| 531 | * @skb: socket buffer the message is stored in | ||
| 532 | * | ||
| 533 | * Returns a pointer to the current tail of the message. | ||
| 534 | */ | ||
| 535 | static inline void *nlmsg_get_pos(struct sk_buff *skb) | ||
| 536 | { | ||
| 537 | return skb->tail; | ||
| 538 | } | ||
| 539 | |||
| 540 | /** | ||
| 541 | * nlmsg_trim - Trim message to a mark | ||
| 542 | * @skb: socket buffer the message is stored in | ||
| 543 | * @mark: mark to trim to | ||
| 544 | * | ||
| 545 | * Trims the message to the provided mark. Returns -1. | ||
| 546 | */ | ||
| 547 | static inline int nlmsg_trim(struct sk_buff *skb, void *mark) | ||
| 548 | { | ||
| 549 | if (mark) | ||
| 550 | skb_trim(skb, (unsigned char *) mark - skb->data); | ||
| 551 | |||
| 552 | return -1; | ||
| 553 | } | ||
| 554 | |||
| 482 | /** | 555 | /** |
| 483 | * nlmsg_cancel - Cancel construction of a netlink message | 556 | * nlmsg_cancel - Cancel construction of a netlink message |
| 484 | * @skb: socket buffer the message is stored in | 557 | * @skb: socket buffer the message is stored in |
| @@ -489,9 +562,7 @@ static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh) · 4 unmodified lines | |||
| 489 | */ | 562 | */ |
| 490 | static inline int nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh) | 563 | static inline int nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh) |
| 491 | { | 564 | { |
| 492 | skb_trim(skb, (unsigned char *) nlh - skb->data); | 565 | return nlmsg_trim(skb, nlh); |
| 493 | |||
| 494 | return -1; | ||
| 495 | } | 566 | } |
| 496 | 567 | ||
| 497 | /** | 568 | /** |
| @@ -509,15 +580,16 @@ static inline void nlmsg_free(struct sk_buff *skb) · 11 unmodified lines | |||
| 509 | * @skb: netlink message as socket buffer | 580 | * @skb: netlink message as socket buffer |
| 510 | * @pid: own netlink pid to avoid sending to yourself | 581 | * @pid: own netlink pid to avoid sending to yourself |
| 511 | * @group: multicast group id | 582 | * @group: multicast group id |
| 583 | * @flags: allocation flags | ||
| 512 | */ | 584 | */ |
| 513 | static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb, | 585 | static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb, |
| 514 | u32 pid, unsigned int group) | 586 | u32 pid, unsigned int group, gfp_t flags) |
| 515 | { | 587 | { |
| 516 | int err; | 588 | int err; |
| 517 | 589 | ||
| 518 | NETLINK_CB(skb).dst_group = group; | 590 | NETLINK_CB(skb).dst_group = group; |
| 519 | 591 | ||
| 520 | err = netlink_broadcast(sk, skb, pid, group, GFP_KERNEL); | 592 | err = netlink_broadcast(sk, skb, pid, group, flags); |
| 521 | if (err > 0) | 593 | if (err > 0) |
| 522 | err = 0; | 594 | err = 0; |
| 523 | 595 | ||
| @@ -630,6 +702,18 @@ static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining) · 106 unmodified lines | |||
| 630 | return (struct nlattr *) ((char *) nla + totlen); | 702 | return (struct nlattr *) ((char *) nla + totlen); |
| 631 | } | 703 | } |
| 632 | 704 | ||
| 705 | /** | ||
| 706 | * nla_find_nested - find attribute in a set of nested attributes | ||
| 707 | * @nla: attribute containing the nested attributes | ||
| 708 | * @attrtype: type of attribute to look for | ||
| 709 | * | ||
| 710 | * Returns the first attribute which matches the specified type. | ||
| 711 | */ | ||
| 712 | static inline struct nlattr *nla_find_nested(struct nlattr *nla, int attrtype) | ||
| 713 | { | ||
| 714 | return nla_find(nla_data(nla), nla_len(nla), attrtype); | ||
| 715 | } | ||
| 716 | |||
| 633 | /** | 717 | /** |
| 634 | * nla_parse_nested - parse nested attributes | 718 | * nla_parse_nested - parse nested attributes |
| 635 | * @tb: destination array with maxtype+1 elements | 719 | * @tb: destination array with maxtype+1 elements |
| @@ -751,7 +835,7 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype, · 115 unmodified lines | |||
| 751 | #define NLA_PUT_STRING(skb, attrtype, value) \ | 835 | #define NLA_PUT_STRING(skb, attrtype, value) \ |
| 752 | NLA_PUT(skb, attrtype, strlen(value) + 1, value) | 836 | NLA_PUT(skb, attrtype, strlen(value) + 1, value) |
| 753 | 837 | ||
| 754 | #define NLA_PUT_FLAG(skb, attrtype, value) \ | 838 | #define NLA_PUT_FLAG(skb, attrtype) \ |
| 755 | NLA_PUT(skb, attrtype, 0, NULL) | 839 | NLA_PUT(skb, attrtype, 0, NULL) |
| 756 | 840 | ||
| 757 | #define NLA_PUT_MSECS(skb, attrtype, jiffies) \ | 841 | #define NLA_PUT_MSECS(skb, attrtype, jiffies) \ |
| @@ -862,10 +946,7 @@ static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start) · 104 unmodified lines | |||
| 862 | */ | 946 | */ |
| 863 | static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start) | 947 | static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start) |
| 864 | { | 948 | { |
| 865 | if (start) | 949 | return nlmsg_trim(skb, start); |
| 866 | skb_trim(skb, (unsigned char *) start - skb->data); | ||
| 867 | |||
| 868 | return -1; | ||
| 869 | } | 950 | } |
| 870 | 951 | ||
| 871 | /** | 952 | /** |
| @@ -880,4 +961,13 @@ static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start) · 8 unmodified lines | |||
| 880 | nla_ok(pos, rem); \ | 961 | nla_ok(pos, rem); \ |
| 881 | pos = nla_next(pos, &(rem))) | 962 | pos = nla_next(pos, &(rem))) |
| 882 | 963 | ||
| 964 | /** | ||
| 965 | * nla_for_each_nested - iterate over nested attributes | ||
| 966 | * @pos: loop counter, set to current attribute | ||
| 967 | * @nla: attribute containing the nested attributes | ||
| 968 | * @rem: initialized to len, holds bytes currently remaining in stream | ||
| 969 | */ | ||
| 970 | #define nla_for_each_nested(pos, nla, rem) \ | ||
| 971 | nla_for_each_attr(pos, nla_data(nla), nla_len(nla), rem) | ||
| 972 | |||
| 883 | #endif | 973 | #endif |
| @@ -0,0 +1,33 @@ | |||
| 1 | #ifndef __NET_NEXTHOP_H | ||
| 2 | #define __NET_NEXTHOP_H | ||
| 3 | |||
| 4 | #include <linux/rtnetlink.h> | ||
| 5 | #include <net/netlink.h> | ||
| 6 | |||
| 7 | static inline int rtnh_ok(const struct rtnexthop *rtnh, int remaining) | ||
| 8 | { | ||
| 9 | return remaining >= sizeof(*rtnh) && | ||
| 10 | rtnh->rtnh_len >= sizeof(*rtnh) && | ||
| 11 | rtnh->rtnh_len <= remaining; | ||
| 12 | } | ||
| 13 | |||
| 14 | static inline struct rtnexthop *rtnh_next(const struct rtnexthop *rtnh, | ||
| 15 | int *remaining) | ||
| 16 | { | ||
| 17 | int totlen = NLA_ALIGN(rtnh->rtnh_len); | ||
| 18 | |||
| 19 | *remaining -= totlen; | ||
| 20 | return (struct rtnexthop *) ((char *) rtnh + totlen); | ||
| 21 | } | ||
| 22 | |||
| 23 | static inline struct nlattr *rtnh_attrs(const struct rtnexthop *rtnh) | ||
| 24 | { | ||
| 25 | return (struct nlattr *) ((char *) rtnh + NLA_ALIGN(sizeof(*rtnh))); | ||
| 26 | } | ||
| 27 | |||
| 28 | static inline int rtnh_attrlen(const struct rtnexthop *rtnh) | ||
| 29 | { | ||
| 30 | return rtnh->rtnh_len - NLA_ALIGN(sizeof(*rtnh)); | ||
| 31 | } | ||
| 32 | |||
| 33 | #endif | ||
| @@ -1,273 +0,0 @@ | |||
| 1 | #ifndef __NET_PKT_ACT_H | ||
| 2 | #define __NET_PKT_ACT_H | ||
| 3 | |||
| 4 | #include <asm/uaccess.h> | ||
| 5 | #include <asm/system.h> | ||
| 6 | #include <linux/bitops.h> | ||
| 7 | #include <linux/types.h> | ||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/sched.h> | ||
| 10 | #include <linux/string.h> | ||
| 11 | #include <linux/mm.h> | ||
| 12 | #include <linux/socket.h> | ||
| 13 | #include <linux/sockios.h> | ||
| 14 | #include <linux/in.h> | ||
| 15 | #include <linux/errno.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/skbuff.h> | ||
| 18 | #include <linux/rtnetlink.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/proc_fs.h> | ||
| 22 | #include <net/sock.h> | ||
| 23 | #include <net/pkt_sched.h> | ||
| 24 | |||
| 25 | #define tca_st(val) (struct tcf_##val *) | ||
| 26 | #define PRIV(a,name) ( tca_st(name) (a)->priv) | ||
| 27 | |||
| 28 | #if 0 /* control */ | ||
| 29 | #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) | ||
| 30 | #else | ||
| 31 | #define DPRINTK(format,args...) | ||
| 32 | #endif | ||
| 33 | |||
| 34 | #if 0 /* data */ | ||
| 35 | #define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args) | ||
| 36 | #else | ||
| 37 | #define D2PRINTK(format,args...) | ||
| 38 | #endif | ||
| 39 | |||
| 40 | static __inline__ unsigned | ||
| 41 | tcf_hash(u32 index) | ||
| 42 | { | ||
| 43 | return index & MY_TAB_MASK; | ||
| 44 | } | ||
| 45 | |||
| 46 | /* probably move this from being inline | ||
| 47 | * and put into act_generic | ||
| 48 | */ | ||
| 49 | static inline void | ||
| 50 | tcf_hash_destroy(struct tcf_st *p) | ||
| 51 | { | ||
| 52 | unsigned h = tcf_hash(p->index); | ||
| 53 | struct tcf_st **p1p; | ||
| 54 | |||
| 55 | for (p1p = &tcf_ht[h]; *p1p; p1p = &(*p1p)->next) { | ||
| 56 | if (*p1p == p) { | ||
| 57 | write_lock_bh(&tcf_t_lock); | ||
| 58 | *p1p = p->next; | ||
| 59 | write_unlock_bh(&tcf_t_lock); | ||
| 60 | #ifdef CONFIG_NET_ESTIMATOR | ||
| 61 | gen_kill_estimator(&p->bstats, &p->rate_est); | ||
| 62 | #endif | ||
| 63 | kfree(p); | ||
| 64 | return; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | BUG_TRAP(0); | ||
| 68 | } | ||
| 69 | |||
| 70 | static inline int | ||
| 71 | tcf_hash_release(struct tcf_st *p, int bind ) | ||
| 72 | { | ||
| 73 | int ret = 0; | ||
| 74 | if (p) { | ||
| 75 | if (bind) { | ||
| 76 | p->bindcnt--; | ||
| 77 | } | ||
| 78 | p->refcnt--; | ||
| 79 | if(p->bindcnt <=0 && p->refcnt <= 0) { | ||
| 80 | tcf_hash_destroy(p); | ||
| 81 | ret = 1; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | return ret; | ||
| 85 | } | ||
| 86 | |||
| 87 | static __inline__ int | ||
| 88 | tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, | ||
| 89 | struct tc_action *a) | ||
| 90 | { | ||
| 91 | struct tcf_st *p; | ||
| 92 | int err =0, index = -1,i= 0, s_i = 0, n_i = 0; | ||
| 93 | struct rtattr *r ; | ||
| 94 | |||
| 95 | read_lock(&tcf_t_lock); | ||
| 96 | |||
| 97 | s_i = cb->args[0]; | ||
| 98 | |||
| 99 | for (i = 0; i < MY_TAB_SIZE; i++) { | ||
| 100 | p = tcf_ht[tcf_hash(i)]; | ||
| 101 | |||
| 102 | for (; p; p = p->next) { | ||
| 103 | index++; | ||
| 104 | if (index < s_i) | ||
| 105 | continue; | ||
| 106 | a->priv = p; | ||
| 107 | a->order = n_i; | ||
| 108 | r = (struct rtattr*) skb->tail; | ||
| 109 | RTA_PUT(skb, a->order, 0, NULL); | ||
| 110 | err = tcf_action_dump_1(skb, a, 0, 0); | ||
| 111 | if (0 > err) { | ||
| 112 | index--; | ||
| 113 | skb_trim(skb, (u8*)r - skb->data); | ||
| 114 | goto done; | ||
| 115 | } | ||
| 116 | r->rta_len = skb->tail - (u8*)r; | ||
| 117 | n_i++; | ||
| 118 | if (n_i >= TCA_ACT_MAX_PRIO) { | ||
| 119 | goto done; | ||
| 120 | } | ||
| 121 | } | ||
| 122 | } | ||
| 123 | done: | ||
| 124 | read_unlock(&tcf_t_lock); | ||
| 125 | if (n_i) | ||
| 126 | cb->args[0] += n_i; | ||
| 127 | return n_i; | ||
| 128 | |||
| 129 | rtattr_failure: | ||
| 130 | skb_trim(skb, (u8*)r - skb->data); | ||
| 131 | goto done; | ||
| 132 | } | ||
| 133 | |||
| 134 | static __inline__ int | ||
| 135 | tcf_del_walker(struct sk_buff *skb, struct tc_action *a) | ||
| 136 | { | ||
| 137 | struct tcf_st *p, *s_p; | ||
| 138 | struct rtattr *r ; | ||
| 139 | int i= 0, n_i = 0; | ||
| 140 | |||
| 141 | r = (struct rtattr*) skb->tail; | ||
| 142 | RTA_PUT(skb, a->order, 0, NULL); | ||
| 143 | RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); | ||
| 144 | for (i = 0; i < MY_TAB_SIZE; i++) { | ||
| 145 | p = tcf_ht[tcf_hash(i)]; | ||
| 146 | |||
| 147 | while (p != NULL) { | ||
| 148 | s_p = p->next; | ||
| 149 | if (ACT_P_DELETED == tcf_hash_release(p, 0)) { | ||
| 150 | module_put(a->ops->owner); | ||
| 151 | } | ||
| 152 | n_i++; | ||
| 153 | p = s_p; | ||
| 154 | } | ||
| 155 | } | ||
| 156 | RTA_PUT(skb, TCA_FCNT, 4, &n_i); | ||
| 157 | r->rta_len = skb->tail - (u8*)r; | ||
| 158 | |||
| 159 | return n_i; | ||
| 160 | rtattr_failure: | ||
| 161 | skb_trim(skb, (u8*)r - skb->data); | ||
| 162 | return -EINVAL; | ||
| 163 | } | ||
| 164 | |||
| 165 | static __inline__ int | ||
| 166 | tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, int type, | ||
| 167 | struct tc_action *a) | ||
| 168 | { | ||
| 169 | if (type == RTM_DELACTION) { | ||
| 170 | return tcf_del_walker(skb,a); | ||
| 171 | } else if (type == RTM_GETACTION) { | ||
| 172 | return tcf_dump_walker(skb,cb,a); | ||
| 173 | } else { | ||
| 174 | printk("tcf_generic_walker: unknown action %d\n",type); | ||
| 175 | return -EINVAL; | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | static __inline__ struct tcf_st * | ||
| 180 | tcf_hash_lookup(u32 index) | ||
| 181 | { | ||
| 182 | struct tcf_st *p; | ||
| 183 | |||
| 184 | read_lock(&tcf_t_lock); | ||
| 185 | for (p = tcf_ht[tcf_hash(index)]; p; p = p->next) { | ||
| 186 | if (p->index == index) | ||
| 187 | break; | ||
| 188 | } | ||
| 189 | read_unlock(&tcf_t_lock); | ||
| 190 | return p; | ||
| 191 | } | ||
| 192 | |||
| 193 | static __inline__ u32 | ||
| 194 | tcf_hash_new_index(void) | ||
| 195 | { | ||
| 196 | do { | ||
| 197 | if (++idx_gen == 0) | ||
| 198 | idx_gen = 1; | ||
| 199 | } while (tcf_hash_lookup(idx_gen)); | ||
| 200 | |||
| 201 | return idx_gen; | ||
| 202 | } | ||
| 203 | |||
| 204 | |||
| 205 | static inline int | ||
| 206 | tcf_hash_search(struct tc_action *a, u32 index) | ||
| 207 | { | ||
| 208 | struct tcf_st *p = tcf_hash_lookup(index); | ||
| 209 | |||
| 210 | if (p != NULL) { | ||
| 211 | a->priv = p; | ||
| 212 | return 1; | ||
| 213 | } | ||
| 214 | return 0; | ||
| 215 | } | ||
| 216 | |||
| 217 | #ifdef CONFIG_NET_ACT_INIT | ||
| 218 | static inline struct tcf_st * | ||
| 219 | tcf_hash_check(u32 index, struct tc_action *a, int ovr, int bind) | ||
| 220 | { | ||
| 221 | struct tcf_st *p = NULL; | ||
| 222 | if (index && (p = tcf_hash_lookup(index)) != NULL) { | ||
| 223 | if (bind) { | ||
| 224 | p->bindcnt++; | ||
| 225 | p->refcnt++; | ||
| 226 | } | ||
| 227 | a->priv = p; | ||
| 228 | } | ||
| 229 | return p; | ||
| 230 | } | ||
| 231 | |||
| 232 | static inline struct tcf_st * | ||
| 233 | tcf_hash_create(u32 index, struct rtattr *est, struct tc_action *a, int size, int ovr, int bind) | ||
| 234 | { | ||
| 235 | struct tcf_st *p = NULL; | ||
| 236 | |||
| 237 | p = kmalloc(size, GFP_KERNEL); | ||
| 238 | if (p == NULL) | ||
| 239 | return p; | ||
| 240 | |||
| 241 | memset(p, 0, size); | ||
| 242 | p->refcnt = 1; | ||
| 243 | |||
| 244 | if (bind) { | ||
| 245 | p->bindcnt = 1; | ||
| 246 | } | ||
| 247 | |||
| 248 | spin_lock_init(&p->lock); | ||
| 249 | p->stats_lock = &p->lock; | ||
| 250 | p->index = index ? : tcf_hash_new_index(); | ||
| 251 | p->tm.install = jiffies; | ||
| 252 | p->tm.lastuse = jiffies; | ||
| 253 | #ifdef CONFIG_NET_ESTIMATOR | ||
| 254 | if (est) | ||
| 255 | gen_new_estimator(&p->bstats, &p->rate_est, p->stats_lock, est); | ||
| 256 | #endif | ||
| 257 | a->priv = (void *) p; | ||
| 258 | return p; | ||
| 259 | } | ||
| 260 | |||
| 261 | static inline void tcf_hash_insert(struct tcf_st *p) | ||
| 262 | { | ||
| 263 | unsigned h = tcf_hash(p->index); | ||
| 264 | |||
| 265 | write_lock_bh(&tcf_t_lock); | ||
| 266 | p->next = tcf_ht[h]; | ||
| 267 | tcf_ht[h] = p; | ||
| 268 | write_unlock_bh(&tcf_t_lock); | ||
| 269 | } | ||
| 270 | |||
| 271 | #endif | ||
| 272 | |||
| 273 | #endif | ||
| @@ -53,6 +53,7 @@ struct request_sock { · 52 unmodified lines | |||
| 53 | unsigned long expires; | 53 | unsigned long expires; |
| 54 | struct request_sock_ops *rsk_ops; | 54 | struct request_sock_ops *rsk_ops; |
| 55 | struct sock *sk; | 55 | struct sock *sk; |
| 56 | u32 secid; | ||
| 56 | }; | 57 | }; |
| 57 | 58 | ||
| 58 | static inline struct request_sock *reqsk_alloc(struct request_sock_ops *ops) | 59 | static inline struct request_sock *reqsk_alloc(struct request_sock_ops *ops) |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | |||
| 32 | #include <linux/route.h> | 32 | #include <linux/route.h> |
| 33 | #include <linux/ip.h> | 33 | #include <linux/ip.h> |
| 34 | #include <linux/cache.h> | 34 | #include <linux/cache.h> |
| 35 | #include <linux/security.h> | ||
| 35 | 36 | ||
| 36 | #ifndef __KERNEL__ | 37 | #ifndef __KERNEL__ |
| 37 | #warning This file is not supposed to be used outside of kernel. | 38 | #warning This file is not supposed to be used outside of kernel. |
| @@ -166,6 +167,7 @@ static inline int ip_route_connect(struct rtable **rp, u32 dst, · 128 unmodified lines | |||
| 166 | ip_rt_put(*rp); | 167 | ip_rt_put(*rp); |
| 167 | *rp = NULL; | 168 | *rp = NULL; |
| 168 | } | 169 | } |
| 170 | security_sk_classify_flow(sk, &fl); | ||
| 169 | return ip_route_output_flow(rp, &fl, sk, 0); | 171 | return ip_route_output_flow(rp, &fl, sk, 0); |
| 170 | } | 172 | } |
| 171 | 173 | ||
| @@ -182,6 +184,7 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol, · 10 unmodified lines | |||
| 182 | fl.proto = protocol; | 184 | fl.proto = protocol; |
| 183 | ip_rt_put(*rp); | 185 | ip_rt_put(*rp); |
| 184 | *rp = NULL; | 186 | *rp = NULL; |
| 187 | security_sk_classify_flow(sk, &fl); | ||
| 185 | return ip_route_output_flow(rp, &fl, sk, 0); | 188 | return ip_route_output_flow(rp, &fl, sk, 0); |
| 186 | } | 189 | } |
| 187 | return 0; | 190 | return 0; |
| @@ -264,10 +264,10 @@ enum { SCTP_MAX_DUP_TSNS = 16 }; · 263 unmodified lines | |||
| 264 | enum { SCTP_MAX_GABS = 16 }; | 264 | enum { SCTP_MAX_GABS = 16 }; |
| 265 | 265 | ||
| 266 | /* Heartbeat interval - 30 secs */ | 266 | /* Heartbeat interval - 30 secs */ |
| 267 | #define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (30 * HZ) | 267 | #define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (30*1000) |
| 268 | 268 | ||
| 269 | /* Delayed sack timer - 200ms */ | 269 | /* Delayed sack timer - 200ms */ |
| 270 | #define SCTP_DEFAULT_TIMEOUT_SACK ((200 * HZ) / 1000) | 270 | #define SCTP_DEFAULT_TIMEOUT_SACK (200) |
| 271 | 271 | ||
| 272 | /* RTO.Initial - 3 seconds | 272 | /* RTO.Initial - 3 seconds |
| 273 | * RTO.Min - 1 second | 273 | * RTO.Min - 1 second |
| @@ -275,9 +275,9 @@ enum { SCTP_MAX_GABS = 16 }; · 1 unmodified line | |||
| 275 | * RTO.Alpha - 1/8 | 275 | * RTO.Alpha - 1/8 |
| 276 | * RTO.Beta - 1/4 | 276 | * RTO.Beta - 1/4 |
| 277 | */ | 277 | */ |
| 278 | #define SCTP_RTO_INITIAL (3 * HZ) | 278 | #define SCTP_RTO_INITIAL (3 * 1000) |
| 279 | #define SCTP_RTO_MIN (1 * HZ) | 279 | #define SCTP_RTO_MIN (1 * 1000) |
| 280 | #define SCTP_RTO_MAX (60 * HZ) | 280 | #define SCTP_RTO_MAX (60 * 1000) |
| 281 | 281 | ||
| 282 | #define SCTP_RTO_ALPHA 3 /* 1/8 when converted to right shifts. */ | 282 | #define SCTP_RTO_ALPHA 3 /* 1/8 when converted to right shifts. */ |
| 283 | #define SCTP_RTO_BETA 2 /* 1/4 when converted to right shifts. */ | 283 | #define SCTP_RTO_BETA 2 /* 1/4 when converted to right shifts. */ |
| @@ -290,8 +290,7 @@ enum { SCTP_MAX_GABS = 16 }; · 6 unmodified lines | |||
| 290 | #define SCTP_DEF_MAX_INIT 6 | 290 | #define SCTP_DEF_MAX_INIT 6 |
| 291 | #define SCTP_DEF_MAX_SEND 10 | 291 | #define SCTP_DEF_MAX_SEND 10 |
| 292 | 292 | ||
| 293 | #define SCTP_DEFAULT_COOKIE_LIFE_SEC 60 /* seconds */ | 293 | #define SCTP_DEFAULT_COOKIE_LIFE (60 * 1000) /* 60 seconds */ |
| 294 | #define SCTP_DEFAULT_COOKIE_LIFE_USEC 0 /* microseconds */ | ||
| 295 | 294 | ||
| 296 | #define SCTP_DEFAULT_MINWINDOW 1500 /* default minimum rwnd size */ | 295 | #define SCTP_DEFAULT_MINWINDOW 1500 /* default minimum rwnd size */ |
| 297 | #define SCTP_DEFAULT_MAXWINDOW 65535 /* default rwnd size */ | 296 | #define SCTP_DEFAULT_MAXWINDOW 65535 /* default rwnd size */ |
| @@ -128,6 +128,8 @@ extern int sctp_copy_local_addr_list(struct sctp_bind_addr *, · 127 unmodified lines | |||
| 128 | int flags); | 128 | int flags); |
| 129 | extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family); | 129 | extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family); |
| 130 | extern int sctp_register_pf(struct sctp_pf *, sa_family_t); | 130 | extern int sctp_register_pf(struct sctp_pf *, sa_family_t); |
| 131 | int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev, | ||
| 132 | void *ptr); | ||
| 131 | 133 | ||
| 132 | /* | 134 | /* |
| 133 | * sctp/socket.c | 135 | * sctp/socket.c |
| @@ -177,6 +179,17 @@ void sctp_icmp_proto_unreachable(struct sock *sk, · 43 unmodified lines | |||
| 177 | void sctp_backlog_migrate(struct sctp_association *assoc, | 179 | void sctp_backlog_migrate(struct sctp_association *assoc, |
| 178 | struct sock *oldsk, struct sock *newsk); | 180 | struct sock *oldsk, struct sock *newsk); |
| 179 | 181 | ||
| 182 | /* | ||
| 183 | * sctp/proc.c | ||
| 184 | */ | ||
| 185 | int sctp_snmp_proc_init(void); | ||
| 186 | void sctp_snmp_proc_exit(void); | ||
| 187 | int sctp_eps_proc_init(void); | ||
| 188 | void sctp_eps_proc_exit(void); | ||
| 189 | int sctp_assocs_proc_init(void); | ||
| 190 | void sctp_assocs_proc_exit(void); | ||
| 191 | |||
| 192 | |||
| 180 | /* | 193 | /* |
| 181 | * Section: Macros, externs, and inlines | 194 | * Section: Macros, externs, and inlines |
| 182 | */ | 195 | */ |
| @@ -216,6 +229,50 @@ DECLARE_SNMP_STAT(struct sctp_mib, sctp_statistics); · 33 unmodified lines | |||
| 216 | 229 | ||
| 217 | #endif /* !TEST_FRAME */ | 230 | #endif /* !TEST_FRAME */ |
| 218 | 231 | ||
| 232 | /* sctp mib definitions */ | ||
| 233 | enum | ||
| 234 | { | ||
| 235 | SCTP_MIB_NUM = 0, | ||
| 236 | SCTP_MIB_CURRESTAB, /* CurrEstab */ | ||
| 237 | SCTP_MIB_ACTIVEESTABS, /* ActiveEstabs */ | ||
| 238 | SCTP_MIB_PASSIVEESTABS, /* PassiveEstabs */ | ||
| 239 | SCTP_MIB_ABORTEDS, /* Aborteds */ | ||
| 240 | SCTP_MIB_SHUTDOWNS, /* Shutdowns */ | ||
| 241 | SCTP_MIB_OUTOFBLUES, /* OutOfBlues */ | ||
| 242 | SCTP_MIB_CHECKSUMERRORS, /* ChecksumErrors */ | ||
| 243 | SCTP_MIB_OUTCTRLCHUNKS, /* OutCtrlChunks */ | ||
| 244 | SCTP_MIB_OUTORDERCHUNKS, /* OutOrderChunks */ | ||
| 245 | SCTP_MIB_OUTUNORDERCHUNKS, /* OutUnorderChunks */ | ||
| 246 | SCTP_MIB_INCTRLCHUNKS, /* InCtrlChunks */ | ||
| 247 | SCTP_MIB_INORDERCHUNKS, /* InOrderChunks */ | ||
| 248 | SCTP_MIB_INUNORDERCHUNKS, /* InUnorderChunks */ | ||
| 249 | SCTP_MIB_FRAGUSRMSGS, /* FragUsrMsgs */ | ||
| 250 | SCTP_MIB_REASMUSRMSGS, /* ReasmUsrMsgs */ | ||
| 251 | SCTP_MIB_OUTSCTPPACKS, /* OutSCTPPacks */ | ||
| 252 | SCTP_MIB_INSCTPPACKS, /* InSCTPPacks */ | ||
| 253 | SCTP_MIB_T1_INIT_EXPIREDS, | ||
| 254 | SCTP_MIB_T1_COOKIE_EXPIREDS, | ||
| 255 | SCTP_MIB_T2_SHUTDOWN_EXPIREDS, | ||
| 256 | SCTP_MIB_T3_RTX_EXPIREDS, | ||
| 257 | SCTP_MIB_T4_RTO_EXPIREDS, | ||
| 258 | SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS, | ||
| 259 | SCTP_MIB_DELAY_SACK_EXPIREDS, | ||
| 260 | SCTP_MIB_AUTOCLOSE_EXPIREDS, | ||
| 261 | SCTP_MIB_T3_RETRANSMITS, | ||
| 262 | SCTP_MIB_PMTUD_RETRANSMITS, | ||
| 263 | SCTP_MIB_FAST_RETRANSMITS, | ||
| 264 | SCTP_MIB_IN_PKT_SOFTIRQ, | ||
| 265 | SCTP_MIB_IN_PKT_BACKLOG, | ||
| 266 | SCTP_MIB_IN_PKT_DISCARDS, | ||
| 267 | SCTP_MIB_IN_DATA_CHUNK_DISCARDS, | ||
| 268 | __SCTP_MIB_MAX | ||
| 269 | }; | ||
| 270 | |||
| 271 | #define SCTP_MIB_MAX __SCTP_MIB_MAX | ||
| 272 | struct sctp_mib { | ||
| 273 | unsigned long mibs[SCTP_MIB_MAX]; | ||
| 274 | } __SNMP_MIB_ALIGN__; | ||
| 275 | |||
| 219 | 276 | ||
| 220 | /* Print debugging messages. */ | 277 | /* Print debugging messages. */ |
| 221 | #if SCTP_DEBUG | 278 | #if SCTP_DEBUG |
| @@ -128,9 +128,9 @@ extern struct sctp_globals { · 127 unmodified lines | |||
| 128 | * RTO.Alpha - 1/8 (3 when converted to right shifts.) | 128 | * RTO.Alpha - 1/8 (3 when converted to right shifts.) |
| 129 | * RTO.Beta - 1/4 (2 when converted to right shifts.) | 129 | * RTO.Beta - 1/4 (2 when converted to right shifts.) |
| 130 | */ | 130 | */ |
| 131 | unsigned long rto_initial; | 131 | unsigned int rto_initial; |
| 132 | unsigned long rto_min; | 132 | unsigned int rto_min; |
| 133 | unsigned long rto_max; | 133 | unsigned int rto_max; |
| 134 | 134 | ||
| 135 | /* Note: rto_alpha and rto_beta are really defined as inverse | 135 | /* Note: rto_alpha and rto_beta are really defined as inverse |
| 136 | * powers of two to facilitate integer operations. | 136 | * powers of two to facilitate integer operations. |
| @@ -145,13 +145,13 @@ extern struct sctp_globals { · 8 unmodified lines | |||
| 145 | int cookie_preserve_enable; | 145 | int cookie_preserve_enable; |
| 146 | 146 | ||
| 147 | /* Valid.Cookie.Life - 60 seconds */ | 147 | /* Valid.Cookie.Life - 60 seconds */ |
| 148 | unsigned long valid_cookie_life; | 148 | unsigned int valid_cookie_life; |
| 149 | 149 | ||
| 150 | /* Delayed SACK timeout 200ms default*/ | 150 | /* Delayed SACK timeout 200ms default*/ |
| 151 | unsigned long sack_timeout; | 151 | unsigned int sack_timeout; |
| 152 | 152 | ||
| 153 | /* HB.interval - 30 seconds */ | 153 | /* HB.interval - 30 seconds */ |
| 154 | unsigned long hb_interval; | 154 | unsigned int hb_interval; |
| 155 | 155 | ||
| 156 | /* Association.Max.Retrans - 10 attempts | 156 | /* Association.Max.Retrans - 10 attempts |
| 157 | * Path.Max.Retrans - 5 attempts (per destination address) | 157 | * Path.Max.Retrans - 5 attempts (per destination address) |
| @@ -100,12 +100,6 @@ struct udp_mib { · 99 unmodified lines | |||
| 100 | unsigned long mibs[UDP_MIB_MAX]; | 100 | unsigned long mibs[UDP_MIB_MAX]; |
| 101 | } __SNMP_MIB_ALIGN__; | 101 | } __SNMP_MIB_ALIGN__; |
| 102 | 102 | ||
| 103 | /* SCTP */ | ||
| 104 | #define SCTP_MIB_MAX __SCTP_MIB_MAX | ||
| 105 | struct sctp_mib { | ||
| 106 | unsigned long mibs[SCTP_MIB_MAX]; | ||
| 107 | } __SNMP_MIB_ALIGN__; | ||
| 108 | |||
| 109 | /* Linux */ | 103 | /* Linux */ |
| 110 | #define LINUX_MIB_MAX __LINUX_MIB_MAX | 104 | #define LINUX_MIB_MAX __LINUX_MIB_MAX |
| 111 | struct linux_mib { | 105 | struct linux_mib { |
| @@ -862,30 +862,24 @@ extern void sock_init_data(struct socket *sock, struct sock *sk); · 861 unmodified lines | |||
| 862 | * | 862 | * |
| 863 | */ | 863 | */ |
| 864 | 864 | ||
| 865 | static inline int sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) | 865 | static inline int sk_filter(struct sock *sk, struct sk_buff *skb) |
| 866 | { | 866 | { |
| 867 | int err; | 867 | int err; |
| 868 | struct sk_filter *filter; | ||
| 868 | 869 | ||
| 869 | err = security_sock_rcv_skb(sk, skb); | 870 | err = security_sock_rcv_skb(sk, skb); |
| 870 | if (err) | 871 | if (err) |
| 871 | return err; | 872 | return err; |
| 872 | 873 | ||
| 873 | if (sk->sk_filter) { | 874 | rcu_read_lock_bh(); |
| 874 | struct sk_filter *filter; | 875 | filter = sk->sk_filter; |
| 875 | 876 | if (filter) { | |
| 876 | if (needlock) | 877 | unsigned int pkt_len = sk_run_filter(skb, filter->insns, |
| 877 | bh_lock_sock(sk); | 878 | filter->len); |
| 878 | 879 | err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM; | |
| 879 | filter = sk->sk_filter; | ||
| 880 | if (filter) { | ||
| 881 | unsigned int pkt_len = sk_run_filter(skb, filter->insns, | ||
| 882 | filter->len); | ||
| 883 | err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM; | ||
| 884 | } | ||
| 885 | |||
| 886 | if (needlock) | ||
| 887 | bh_unlock_sock(sk); | ||
| 888 | } | 880 | } |
| 881 | rcu_read_unlock_bh(); | ||
| 882 | |||
| 889 | return err; | 883 | return err; |
| 890 | } | 884 | } |
| 891 | 885 | ||
| @@ -897,6 +891,12 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) · 5 unmodified lines | |||
| 897 | * Remove a filter from a socket and release its resources. | 891 | * Remove a filter from a socket and release its resources. |
| 898 | */ | 892 | */ |
| 899 | 893 | ||
| 894 | static inline void sk_filter_rcu_free(struct rcu_head *rcu) | ||
| 895 | { | ||
| 896 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); | ||
| 897 | kfree(fp); | ||
| 898 | } | ||
| 899 | |||
| 900 | static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp) | 900 | static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp) |
| 901 | { | 901 | { |
| 902 | unsigned int size = sk_filter_len(fp); | 902 | unsigned int size = sk_filter_len(fp); |
| @@ -904,7 +904,7 @@ static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp) · 1 unmodified line | |||
| 904 | atomic_sub(size, &sk->sk_omem_alloc); | 904 | atomic_sub(size, &sk->sk_omem_alloc); |
| 905 | 905 | ||
| 906 | if (atomic_dec_and_test(&fp->refcnt)) | 906 | if (atomic_dec_and_test(&fp->refcnt)) |
| 907 | kfree(fp); | 907 | call_rcu_bh(&fp->rcu, sk_filter_rcu_free); |
| 908 | } | 908 | } |
| 909 | 909 | ||
| 910 | static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp) | 910 | static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp) |
| @@ -969,9 +969,23 @@ static inline void sock_graft(struct sock *sk, struct socket *parent) · 58 unmodified lines | |||
| 969 | sk->sk_sleep = &parent->wait; | 969 | sk->sk_sleep = &parent->wait; |
| 970 | parent->sk = sk; | 970 | parent->sk = sk; |
| 971 | sk->sk_socket = parent; | 971 | sk->sk_socket = parent; |
| 972 | security_sock_graft(sk, parent); | ||
| 972 | write_unlock_bh(&sk->sk_callback_lock); | 973 | write_unlock_bh(&sk->sk_callback_lock); |
| 973 | } | 974 | } |
| 974 | 975 | ||
| 976 | static inline void sock_copy(struct sock *nsk, const struct sock *osk) | ||
| 977 | { | ||
| 978 | #ifdef CONFIG_SECURITY_NETWORK | ||
| 979 | void *sptr = nsk->sk_security; | ||
| 980 | #endif | ||
| 981 | |||
| 982 | memcpy(nsk, osk, osk->sk_prot->obj_size); | ||
| 983 | #ifdef CONFIG_SECURITY_NETWORK | ||
| 984 | nsk->sk_security = sptr; | ||
| 985 | security_sk_clone(osk, nsk); | ||
| 986 | #endif | ||
| 987 | } | ||
| 988 | |||
| 975 | extern int sock_i_uid(struct sock *sk); | 989 | extern int sock_i_uid(struct sock *sk); |
| 976 | extern unsigned long sock_i_ino(struct sock *sk); | 990 | extern unsigned long sock_i_ino(struct sock *sk); |
| 977 | 991 | ||
| @@ -3,11 +3,12 @@ · 2 unmodified lines | |||
| 3 | 3 | ||
| 4 | #include <net/act_api.h> | 4 | #include <net/act_api.h> |
| 5 | 5 | ||
| 6 | struct tcf_defact | 6 | struct tcf_defact { |
| 7 | { | 7 | struct tcf_common common; |
| 8 | tca_gen(defact); | 8 | u32 tcfd_datalen; |
| 9 | u32 datalen; | 9 | void *tcfd_defdata; |
| 10 | void *defdata; | ||
| 11 | }; | 10 | }; |
| 11 | #define to_defact(pc) \ | ||
| 12 | container_of(pc, struct tcf_defact, common) | ||
| 12 | 13 | ||
| 13 | #endif | 14 | #endif /* __NET_TC_DEF_H */ |
| @@ -3,15 +3,15 @@ · 2 unmodified lines | |||
| 3 | 3 | ||
| 4 | #include <net/act_api.h> | 4 | #include <net/act_api.h> |
| 5 | 5 | ||
| 6 | struct tcf_gact | 6 | struct tcf_gact { |
| 7 | { | 7 | struct tcf_common common; |
| 8 | tca_gen(gact); | ||
| 9 | #ifdef CONFIG_GACT_PROB | 8 | #ifdef CONFIG_GACT_PROB |
| 10 | u16 ptype; | 9 | u16 tcfg_ptype; |
| 11 | u16 pval; | 10 | u16 tcfg_pval; |
| 12 | int paction; | 11 | int tcfg_paction; |
| 13 | #endif | 12 | #endif |
| 14 | |||
| 15 | }; | 13 | }; |
| 16 | 14 | #define to_gact(pc) \ | |
| 17 | #endif | 15 | container_of(pc, struct tcf_gact, common) |
| 16 | |||
| 17 | #endif /* __NET_TC_GACT_H */ | ||
| @@ -5,12 +5,13 @@ · 4 unmodified lines | |||
| 5 | 5 | ||
| 6 | struct xt_entry_target; | 6 | struct xt_entry_target; |
| 7 | 7 | ||
| 8 | struct tcf_ipt | 8 | struct tcf_ipt { |
| 9 | { | 9 | struct tcf_common common; |
| 10 | tca_gen(ipt); | 10 | u32 tcfi_hook; |
| 11 | u32 hook; | 11 | char *tcfi_tname; |
| 12 | char *tname; | 12 | struct xt_entry_target *tcfi_t; |
| 13 | struct xt_entry_target *t; | ||
| 14 | }; | 13 | }; |
| 14 | #define to_ipt(pc) \ | ||
| 15 | container_of(pc, struct tcf_ipt, common) | ||
| 15 | 16 | ||
| 16 | #endif | 17 | #endif /* __NET_TC_IPT_H */ |
| @@ -3,13 +3,14 @@ · 2 unmodified lines | |||
| 3 | 3 | ||
| 4 | #include <net/act_api.h> | 4 | #include <net/act_api.h> |
| 5 | 5 | ||
| 6 | struct tcf_mirred | 6 | struct tcf_mirred { |
| 7 | { | 7 | struct tcf_common common; |
| 8 | tca_gen(mirred); | 8 | int tcfm_eaction; |
| 9 | int eaction; | 9 | int tcfm_ifindex; |
| 10 | int ifindex; | 10 | int tcfm_ok_push; |
| 11 | int ok_push; | 11 | struct net_device *tcfm_dev; |
| 12 | struct net_device *dev; | ||
| 13 | }; | 12 | }; |
| 13 | #define to_mirred(pc) \ | ||
| 14 | container_of(pc, struct tcf_mirred, common) | ||
| 14 | 15 | ||
| 15 | #endif | 16 | #endif /* __NET_TC_MIR_H */ |
| @@ -3,12 +3,13 @@ · 2 unmodified lines | |||
| 3 | 3 | ||
| 4 | #include <net/act_api.h> | 4 | #include <net/act_api.h> |
| 5 | 5 | ||
| 6 | struct tcf_pedit | 6 | struct tcf_pedit { |
| 7 | { | 7 | struct tcf_common common; |
| 8 | tca_gen(pedit); | 8 | unsigned char tcfp_nkeys; |
| 9 | unsigned char nkeys; | 9 | unsigned char tcfp_flags; |
| 10 | unsigned char flags; | 10 | struct tc_pedit_key *tcfp_keys; |
| 11 | struct tc_pedit_key *keys; | ||
| 12 | }; | 11 | }; |
| 12 | #define to_pedit(pc) \ | ||
| 13 | container_of(pc, struct tcf_pedit, common) | ||
| 13 | 14 | ||
| 14 | #endif | 15 | #endif /* __NET_TC_PED_H */ |
| @@ -30,25 +30,9 @@ · 29 unmodified lines | |||
| 30 | 30 | ||
| 31 | #define UDP_HTABLE_SIZE 128 | 31 | #define UDP_HTABLE_SIZE 128 |
| 32 | 32 | ||
| 33 | /* udp.c: This needs to be shared by v4 and v6 because the lookup | ||
| 34 | * and hashing code needs to work with different AF's yet | ||
| 35 | * the port space is shared. | ||
| 36 | */ | ||
| 37 | extern struct hlist_head udp_hash[UDP_HTABLE_SIZE]; | 33 | extern struct hlist_head udp_hash[UDP_HTABLE_SIZE]; |
| 38 | extern rwlock_t udp_hash_lock; | 34 | extern rwlock_t udp_hash_lock; |
| 39 | 35 | ||
| 40 | extern int udp_port_rover; | ||
| 41 | |||
| 42 | static inline int udp_lport_inuse(u16 num) | ||
| 43 | { | ||
| 44 | struct sock *sk; | ||
| 45 | struct hlist_node *node; | ||
| 46 | |||
| 47 | sk_for_each(sk, node, &udp_hash[num & (UDP_HTABLE_SIZE - 1)]) | ||
| 48 | if (inet_sk(sk)->num == num) | ||
| 49 | return 1; | ||
| 50 | return 0; | ||
| 51 | } | ||
| 52 | 36 | ||
| 53 | /* Note: this must match 'valbool' in sock_setsockopt */ | 37 | /* Note: this must match 'valbool' in sock_setsockopt */ |
| 54 | #define UDP_CSUM_NOXMIT 1 | 38 | #define UDP_CSUM_NOXMIT 1 |
| @@ -63,6 +47,8 @@ extern struct proto udp_prot; · 8 unmodified lines | |||
| 63 | 47 | ||
| 64 | struct sk_buff; | 48 | struct sk_buff; |
| 65 | 49 | ||
| 50 | extern int udp_get_port(struct sock *sk, unsigned short snum, | ||
| 51 | int (*saddr_cmp)(const struct sock *, const struct sock *)); | ||
| 66 | extern void udp_err(struct sk_buff *, u32); | 52 | extern void udp_err(struct sk_buff *, u32); |
| 67 | 53 | ||
| 68 | extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk, | 54 | extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk, |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | #include <linux/skbuff.h> | 9 | #include <linux/skbuff.h> |
| 10 | #include <linux/socket.h> | 10 | #include <linux/socket.h> |
| 11 | #include <linux/pfkeyv2.h> | 11 | #include <linux/pfkeyv2.h> |
| 12 | #include <linux/ipsec.h> | ||
| 12 | #include <linux/in6.h> | 13 | #include <linux/in6.h> |
| 13 | #include <linux/mutex.h> | 14 | #include <linux/mutex.h> |
| 14 | 15 | ||
| @@ -93,8 +94,9 @@ extern struct mutex xfrm_cfg_mutex; · 78 unmodified lines | |||
| 93 | struct xfrm_state | 94 | struct xfrm_state |
| 94 | { | 95 | { |
| 95 | /* Note: bydst is re-used during gc */ | 96 | /* Note: bydst is re-used during gc */ |
| 96 | struct list_head bydst; | 97 | struct hlist_node bydst; |
| 97 | struct list_head byspi; | 98 | struct hlist_node bysrc; |
| 99 | struct hlist_node byspi; | ||
| 98 | 100 | ||
| 99 | atomic_t refcnt; | 101 | atomic_t refcnt; |
| 100 | spinlock_t lock; | 102 | spinlock_t lock; |
| @@ -102,6 +104,8 @@ struct xfrm_state · 1 unmodified line | |||
| 102 | struct xfrm_id id; | 104 | struct xfrm_id id; |
| 103 | struct xfrm_selector sel; | 105 | struct xfrm_selector sel; |
| 104 | 106 | ||
| 107 | u32 genid; | ||
| 108 | |||
| 105 | /* Key manger bits */ | 109 | /* Key manger bits */ |
| 106 | struct { | 110 | struct { |
| 107 | u8 state; | 111 | u8 state; |
| @@ -132,6 +136,9 @@ struct xfrm_state · 24 unmodified lines | |||
| 132 | /* Data for encapsulator */ | 136 | /* Data for encapsulator */ |
| 133 | struct xfrm_encap_tmpl *encap; | 137 | struct xfrm_encap_tmpl *encap; |
| 134 | 138 | ||
| 139 | /* Data for care-of address */ | ||
| 140 | xfrm_address_t *coaddr; | ||
| 141 | |||
| 135 | /* IPComp needs an IPIP tunnel for handling uncompressed packets */ | 142 | /* IPComp needs an IPIP tunnel for handling uncompressed packets */ |
| 136 | struct xfrm_state *tunnel; | 143 | struct xfrm_state *tunnel; |
| 137 | 144 | ||
| @@ -162,6 +169,9 @@ struct xfrm_state · 24 unmodified lines | |||
| 162 | struct xfrm_lifetime_cur curlft; | 169 | struct xfrm_lifetime_cur curlft; |
| 163 | struct timer_list timer; | 170 | struct timer_list timer; |
| 164 | 171 | ||
| 172 | /* Last used time */ | ||
| 173 | u64 lastused; | ||
| 174 | |||
| 165 | /* Reference to data common to all the instances of this | 175 | /* Reference to data common to all the instances of this |
| 166 | * transformer. */ | 176 | * transformer. */ |
| 167 | struct xfrm_type *type; | 177 | struct xfrm_type *type; |
| @@ -195,6 +205,7 @@ struct km_event · 27 unmodified lines | |||
| 195 | u32 proto; | 205 | u32 proto; |
| 196 | u32 byid; | 206 | u32 byid; |
| 197 | u32 aevent; | 207 | u32 aevent; |
| 208 | u32 type; | ||
| 198 | } data; | 209 | } data; |
| 199 | 210 | ||
| 200 | u32 seq; | 211 | u32 seq; |
| @@ -211,6 +222,7 @@ struct xfrm_policy_afinfo { · 10 unmodified lines | |||
| 211 | struct dst_ops *dst_ops; | 222 | struct dst_ops *dst_ops; |
| 212 | void (*garbage_collect)(void); | 223 | void (*garbage_collect)(void); |
| 213 | int (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl); | 224 | int (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl); |
| 225 | int (*get_saddr)(xfrm_address_t *saddr, xfrm_address_t *daddr); | ||
| 214 | struct dst_entry *(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy); | 226 | struct dst_entry *(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy); |
| 215 | int (*bundle_create)(struct xfrm_policy *policy, | 227 | int (*bundle_create)(struct xfrm_policy *policy, |
| 216 | struct xfrm_state **xfrm, | 228 | struct xfrm_state **xfrm, |
| @@ -234,16 +246,12 @@ extern int __xfrm_state_delete(struct xfrm_state *x); · 17 unmodified lines | |||
| 234 | 246 | ||
| 235 | struct xfrm_state_afinfo { | 247 | struct xfrm_state_afinfo { |
| 236 | unsigned short family; | 248 | unsigned short family; |
| 237 | struct list_head *state_bydst; | ||
| 238 | struct list_head *state_byspi; | ||
| 239 | int (*init_flags)(struct xfrm_state *x); | 249 | int (*init_flags)(struct xfrm_state *x); |
| 240 | void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl, | 250 | void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl, |
| 241 | struct xfrm_tmpl *tmpl, | 251 | struct xfrm_tmpl *tmpl, |
| 242 | xfrm_address_t *daddr, xfrm_address_t *saddr); | 252 | xfrm_address_t *daddr, xfrm_address_t *saddr); |
| 243 | struct xfrm_state *(*state_lookup)(xfrm_address_t *daddr, u32 spi, u8 proto); | 253 | int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n); |
| 244 | struct xfrm_state *(*find_acq)(u8 mode, u32 reqid, u8 proto, | 254 | int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n); |
| 245 | xfrm_address_t *daddr, xfrm_address_t *saddr, | ||
| 246 | int create); | ||
| 247 | }; | 255 | }; |
| 248 | 256 | ||
| 249 | extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo); | 257 | extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo); |
| @@ -256,11 +264,17 @@ struct xfrm_type · 6 unmodified lines | |||
| 256 | char *description; | 264 | char *description; |
| 257 | struct module *owner; | 265 | struct module *owner; |
| 258 | __u8 proto; | 266 | __u8 proto; |
| 267 | __u8 flags; | ||
| 268 | #define XFRM_TYPE_NON_FRAGMENT 1 | ||
| 259 | 269 | ||
| 260 | int (*init_state)(struct xfrm_state *x); | 270 | int (*init_state)(struct xfrm_state *x); |
| 261 | void (*destructor)(struct xfrm_state *); | 271 | void (*destructor)(struct xfrm_state *); |
| 262 | int (*input)(struct xfrm_state *, struct sk_buff *skb); | 272 | int (*input)(struct xfrm_state *, struct sk_buff *skb); |
| 263 | int (*output)(struct xfrm_state *, struct sk_buff *pskb); | 273 | int (*output)(struct xfrm_state *, struct sk_buff *pskb); |
| 274 | int (*reject)(struct xfrm_state *, struct sk_buff *, struct flowi *); | ||
| 275 | int (*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **); | ||
| 276 | xfrm_address_t *(*local_addr)(struct xfrm_state *, xfrm_address_t *); | ||
| 277 | xfrm_address_t *(*remote_addr)(struct xfrm_state *, xfrm_address_t *); | ||
| 264 | /* Estimate maximal size of result of transformation of a dgram */ | 278 | /* Estimate maximal size of result of transformation of a dgram */ |
| 265 | u32 (*get_max_size)(struct xfrm_state *, int size); | 279 | u32 (*get_max_size)(struct xfrm_state *, int size); |
| 266 | }; | 280 | }; |
| @@ -272,7 +286,7 @@ extern void xfrm_put_type(struct xfrm_type *type); · 5 unmodified lines | |||
| 272 | 286 | ||
| 273 | struct xfrm_mode { | 287 | struct xfrm_mode { |
| 274 | int (*input)(struct xfrm_state *x, struct sk_buff *skb); | 288 | int (*input)(struct xfrm_state *x, struct sk_buff *skb); |
| 275 | int (*output)(struct sk_buff *skb); | 289 | int (*output)(struct xfrm_state *x,struct sk_buff *skb); |
| 276 | 290 | ||
| 277 | struct module *owner; | 291 | struct module *owner; |
| 278 | unsigned int encap; | 292 | unsigned int encap; |
| @@ -298,7 +312,7 @@ struct xfrm_tmpl · 19 unmodified lines | |||
| 298 | 312 | ||
| 299 | __u32 reqid; | 313 | __u32 reqid; |
| 300 | 314 | ||
| 301 | /* Mode: transport/tunnel */ | 315 | /* Mode: transport, tunnel etc. */ |
| 302 | __u8 mode; | 316 | __u8 mode; |
| 303 | 317 | ||
| 304 | /* Sharing mode: unique, this session only, this user only etc. */ | 318 | /* Sharing mode: unique, this session only, this user only etc. */ |
| @@ -313,18 +327,20 @@ struct xfrm_tmpl · 8 unmodified lines | |||
| 313 | __u32 calgos; | 327 | __u32 calgos; |
| 314 | }; | 328 | }; |
| 315 | 329 | ||
| 316 | #define XFRM_MAX_DEPTH 4 | 330 | #define XFRM_MAX_DEPTH 6 |
| 317 | 331 | ||
| 318 | struct xfrm_policy | 332 | struct xfrm_policy |
| 319 | { | 333 | { |
| 320 | struct xfrm_policy *next; | 334 | struct xfrm_policy *next; |
| 321 | struct list_head list; | 335 | struct hlist_node bydst; |
| 336 | struct hlist_node byidx; | ||
| 322 | 337 | ||
| 323 | /* This lock only affects elements except for entry. */ | 338 | /* This lock only affects elements except for entry. */ |
| 324 | rwlock_t lock; | 339 | rwlock_t lock; |
| 325 | atomic_t refcnt; | 340 | atomic_t refcnt; |
| 326 | struct timer_list timer; | 341 | struct timer_list timer; |
| 327 | 342 | ||
| 343 | u8 type; | ||
| 328 | u32 priority; | 344 | u32 priority; |
| 329 | u32 index; | 345 | u32 index; |
| 330 | struct xfrm_selector selector; | 346 | struct xfrm_selector selector; |
| @@ -362,16 +378,16 @@ struct xfrm_mgr · 31 unmodified lines | |||
| 362 | char *id; | 378 | char *id; |
| 363 | int (*notify)(struct xfrm_state *x, struct km_event *c); | 379 | int (*notify)(struct xfrm_state *x, struct km_event *c); |
| 364 | int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp, int dir); | 380 | int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp, int dir); |
| 365 | struct xfrm_policy *(*compile_policy)(u16 family, int opt, u8 *data, int len, int *dir); | 381 | struct xfrm_policy *(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir); |
| 366 | int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport); | 382 | int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport); |
| 367 | int (*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c); | 383 | int (*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c); |
| 384 | int (*report)(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr); | ||
| 368 | }; | 385 | }; |
| 369 | 386 | ||
| 370 | extern int xfrm_register_km(struct xfrm_mgr *km); | 387 | extern int xfrm_register_km(struct xfrm_mgr *km); |
| 371 | extern int xfrm_unregister_km(struct xfrm_mgr *km); | 388 | extern int xfrm_unregister_km(struct xfrm_mgr *km); |
| 372 | 389 | ||
| 373 | 390 | extern unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2]; | |
| 374 | extern struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2]; | ||
| 375 | 391 | ||
| 376 | static inline void xfrm_pol_hold(struct xfrm_policy *policy) | 392 | static inline void xfrm_pol_hold(struct xfrm_policy *policy) |
| 377 | { | 393 | { |
| @@ -387,67 +403,19 @@ static inline void xfrm_pol_put(struct xfrm_policy *policy) · 9 unmodified lines | |||
| 387 | __xfrm_policy_destroy(policy); | 403 | __xfrm_policy_destroy(policy); |
| 388 | } | 404 | } |
| 389 | 405 | ||
| 390 | #define XFRM_DST_HSIZE 1024 | 406 | #ifdef CONFIG_XFRM_SUB_POLICY |
| 391 | 407 | static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols) | |
| 392 | static __inline__ | ||
| 393 | unsigned __xfrm4_dst_hash(xfrm_address_t *addr) | ||
| 394 | { | ||
| 395 | unsigned h; | ||
| 396 | h = ntohl(addr->a4); | ||
| 397 | h = (h ^ (h>>16)) % XFRM_DST_HSIZE; | ||
| 398 | return h; | ||
| 399 | } | ||
| 400 | |||
| 401 | static __inline__ | ||
| 402 | unsigned __xfrm6_dst_hash(xfrm_address_t *addr) | ||
| 403 | { | ||
| 404 | unsigned h; | ||
| 405 | h = ntohl(addr->a6[2]^addr->a6[3]); | ||
| 406 | h = (h ^ (h>>16)) % XFRM_DST_HSIZE; | ||
| 407 | return h; | ||
| 408 | } | ||
| 409 | |||
| 410 | static __inline__ | ||
| 411 | unsigned xfrm_dst_hash(xfrm_address_t *addr, unsigned short family) | ||
| 412 | { | ||
| 413 | switch (family) { | ||
| 414 | case AF_INET: | ||
| 415 | return __xfrm4_dst_hash(addr); | ||
| 416 | case AF_INET6: | ||
| 417 | return __xfrm6_dst_hash(addr); | ||
| 418 | } | ||
| 419 | return 0; | ||
| 420 | } | ||
| 421 | |||
| 422 | static __inline__ | ||
| 423 | unsigned __xfrm4_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto) | ||
| 424 | { | 408 | { |
| 425 | unsigned h; | 409 | int i; |
| 426 | h = ntohl(addr->a4^spi^proto); | 410 | for (i = npols - 1; i >= 0; --i) |
| 427 | h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE; | 411 | xfrm_pol_put(pols[i]); |
| 428 | return h; | ||
| 429 | } | 412 | } |
| 430 | 413 | #else | |
| 431 | static __inline__ | 414 | static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols) |
| 432 | unsigned __xfrm6_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto) | ||
| 433 | { | ||
| 434 | unsigned h; | ||
| 435 | h = ntohl(addr->a6[2]^addr->a6[3]^spi^proto); | ||
| 436 | h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE; | ||
| 437 | return h; | ||
| 438 | } | ||
| 439 | |||
| 440 | static __inline__ | ||
| 441 | unsigned xfrm_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto, unsigned short family) | ||
| 442 | { | 415 | { |
| 443 | switch (family) { | 416 | xfrm_pol_put(pols[0]); |
| 444 | case AF_INET: | ||
| 445 | return __xfrm4_spi_hash(addr, spi, proto); | ||
| 446 | case AF_INET6: | ||
| 447 | return __xfrm6_spi_hash(addr, spi, proto); | ||
| 448 | } | ||
| 449 | return 0; /*XXX*/ | ||
| 450 | } | 417 | } |
| 418 | #endif | ||
| 451 | 419 | ||
| 452 | extern void __xfrm_state_destroy(struct xfrm_state *); | 420 | extern void __xfrm_state_destroy(struct xfrm_state *); |
| 453 | 421 | ||
| @@ -507,6 +475,11 @@ u16 xfrm_flowi_sport(struct flowi *fl) · 53 unmodified lines | |||
| 507 | case IPPROTO_ICMPV6: | 475 | case IPPROTO_ICMPV6: |
| 508 | port = htons(fl->fl_icmp_type); | 476 | port = htons(fl->fl_icmp_type); |
| 509 | break; | 477 | break; |
| 478 | #ifdef CONFIG_IPV6_MIP6 | ||
| 479 | case IPPROTO_MH: | ||
| 480 | port = htons(fl->fl_mh_type); | ||
| 481 | break; | ||
| 482 | #endif | ||
| 510 | default: | 483 | default: |
| 511 | port = 0; /*XXX*/ | 484 | port = 0; /*XXX*/ |
| 512 | } | 485 | } |
| @@ -607,6 +580,7 @@ struct xfrm_dst · 94 unmodified lines | |||
| 607 | struct rt6_info rt6; | 580 | struct rt6_info rt6; |
| 608 | } u; | 581 | } u; |
| 609 | struct dst_entry *route; | 582 | struct dst_entry *route; |
| 583 | u32 genid; | ||
| 610 | u32 route_mtu_cached; | 584 | u32 route_mtu_cached; |
| 611 | u32 child_mtu_cached; | 585 | u32 child_mtu_cached; |
| 612 | u32 route_cookie; | 586 | u32 route_cookie; |
| @@ -657,6 +631,18 @@ secpath_reset(struct sk_buff *skb) · 44 unmodified lines | |||
| 657 | #endif | 631 | #endif |
| 658 | } | 632 | } |
| 659 | 633 | ||
| 634 | static inline int | ||
| 635 | xfrm_addr_any(xfrm_address_t *addr, unsigned short family) | ||
| 636 | { | ||
| 637 | switch (family) { | ||
| 638 | case AF_INET: | ||
| 639 | return addr->a4 == 0; | ||
| 640 | case AF_INET6: | ||
| 641 | return ipv6_addr_any((struct in6_addr *)&addr->a6); | ||
| 642 | } | ||
| 643 | return 0; | ||
| 644 | } | ||
| 645 | |||
| 660 | static inline int | 646 | static inline int |
| 661 | __xfrm4_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x) | 647 | __xfrm4_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x) |
| 662 | { | 648 | { |
| @@ -691,8 +677,8 @@ static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *sk · 28 unmodified lines | |||
| 691 | { | 677 | { |
| 692 | if (sk && sk->sk_policy[XFRM_POLICY_IN]) | 678 | if (sk && sk->sk_policy[XFRM_POLICY_IN]) |
| 693 | return __xfrm_policy_check(sk, dir, skb, family); | 679 | return __xfrm_policy_check(sk, dir, skb, family); |
| 694 | 680 | ||
| 695 | return (!xfrm_policy_list[dir] && !skb->sp) || | 681 | return (!xfrm_policy_count[dir] && !skb->sp) || |
| 696 | (skb->dst->flags & DST_NOPOLICY) || | 682 | (skb->dst->flags & DST_NOPOLICY) || |
| 697 | __xfrm_policy_check(sk, dir, skb, family); | 683 | __xfrm_policy_check(sk, dir, skb, family); |
| 698 | } | 684 | } |
| @@ -712,7 +698,7 @@ extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family); · 13 unmodified lines | |||
| 712 | 698 | ||
| 713 | static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) | 699 | static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) |
| 714 | { | 700 | { |
| 715 | return !xfrm_policy_list[XFRM_POLICY_OUT] || | 701 | return !xfrm_policy_count[XFRM_POLICY_OUT] || |
| 716 | (skb->dst->flags & DST_NOXFRM) || | 702 | (skb->dst->flags & DST_NOXFRM) || |
| 717 | __xfrm_route_forward(skb, family); | 703 | __xfrm_route_forward(skb, family); |
| 718 | } | 704 | } |
| @@ -830,11 +816,36 @@ xfrm_state_addr_check(struct xfrm_state *x, · 111 unmodified lines | |||
| 830 | return 0; | 816 | return 0; |
| 831 | } | 817 | } |
| 832 | 818 | ||
| 819 | static __inline__ int | ||
| 820 | xfrm_state_addr_flow_check(struct xfrm_state *x, struct flowi *fl, | ||
| 821 | unsigned short family) | ||
| 822 | { | ||
| 823 | switch (family) { | ||
| 824 | case AF_INET: | ||
| 825 | return __xfrm4_state_addr_check(x, | ||
| 826 | (xfrm_address_t *)&fl->fl4_dst, | ||
| 827 | (xfrm_address_t *)&fl->fl4_src); | ||
| 828 | case AF_INET6: | ||
| 829 | return __xfrm6_state_addr_check(x, | ||
| 830 | (xfrm_address_t *)&fl->fl6_dst, | ||
| 831 | (xfrm_address_t *)&fl->fl6_src); | ||
| 832 | } | ||
| 833 | return 0; | ||
| 834 | } | ||
| 835 | |||
| 833 | static inline int xfrm_state_kern(struct xfrm_state *x) | 836 | static inline int xfrm_state_kern(struct xfrm_state *x) |
| 834 | { | 837 | { |
| 835 | return atomic_read(&x->tunnel_users); | 838 | return atomic_read(&x->tunnel_users); |
| 836 | } | 839 | } |
| 837 | 840 | ||
| 841 | static inline int xfrm_id_proto_match(u8 proto, u8 userproto) | ||
| 842 | { | ||
| 843 | return (!userproto || proto == userproto || | ||
| 844 | (userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH || | ||
| 845 | proto == IPPROTO_ESP || | ||
| 846 | proto == IPPROTO_COMP))); | ||
| 847 | } | ||
| 848 | |||
| 838 | /* | 849 | /* |
| 839 | * xfrm algorithm information | 850 | * xfrm algorithm information |
| 840 | */ | 851 | */ |
| @@ -902,6 +913,25 @@ extern void xfrm_state_insert(struct xfrm_state *x); · 61 unmodified lines | |||
| 902 | extern int xfrm_state_add(struct xfrm_state *x); | 913 | extern int xfrm_state_add(struct xfrm_state *x); |
| 903 | extern int xfrm_state_update(struct xfrm_state *x); | 914 | extern int xfrm_state_update(struct xfrm_state *x); |
| 904 | extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family); | 915 | extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family); |
| 916 | extern struct xfrm_state *xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family); | ||
| 917 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
| 918 | extern int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, | ||
| 919 | int n, unsigned short family); | ||
| 920 | extern int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, | ||
| 921 | int n, unsigned short family); | ||
| 922 | #else | ||
| 923 | static inline int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, | ||
| 924 | int n, unsigned short family) | ||
| 925 | { | ||
| 926 | return -ENOSYS; | ||
| 927 | } | ||
| 928 | |||
| 929 | static inline int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, | ||
| 930 | int n, unsigned short family) | ||
| 931 | { | ||
| 932 | return -ENOSYS; | ||
| 933 | } | ||
| 934 | #endif | ||
| 905 | extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); | 935 | extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); |
| 906 | extern int xfrm_state_delete(struct xfrm_state *x); | 936 | extern int xfrm_state_delete(struct xfrm_state *x); |
| 907 | extern void xfrm_state_flush(u8 proto); | 937 | extern void xfrm_state_flush(u8 proto); |
| @@ -917,12 +947,16 @@ extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler); · 9 unmodified lines | |||
| 917 | extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler); | 947 | extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler); |
| 918 | extern int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi); | 948 | extern int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi); |
| 919 | extern int xfrm6_rcv(struct sk_buff **pskb); | 949 | extern int xfrm6_rcv(struct sk_buff **pskb); |
| 950 | extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, | ||
| 951 | xfrm_address_t *saddr, u8 proto); | ||
| 920 | extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler); | 952 | extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler); |
| 921 | extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler); | 953 | extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler); |
| 922 | extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr); | 954 | extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr); |
| 923 | extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr); | 955 | extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr); |
| 924 | extern u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr); | 956 | extern u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr); |
| 925 | extern int xfrm6_output(struct sk_buff *skb); | 957 | extern int xfrm6_output(struct sk_buff *skb); |
| 958 | extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, | ||
| 959 | u8 **prevhdr); | ||
| 926 | 960 | ||
| 927 | #ifdef CONFIG_XFRM | 961 | #ifdef CONFIG_XFRM |
| 928 | extern int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type); | 962 | extern int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type); |
| @@ -947,27 +981,27 @@ static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsig · 18 unmodified lines | |||
| 947 | #endif | 981 | #endif |
| 948 | 982 | ||
| 949 | struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp); | 983 | struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp); |
| 950 | extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *); | 984 | extern int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), void *); |
| 951 | int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); | 985 | int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); |
| 952 | struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel, | 986 | struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, |
| 987 | struct xfrm_selector *sel, | ||
| 953 | struct xfrm_sec_ctx *ctx, int delete); | 988 | struct xfrm_sec_ctx *ctx, int delete); |
| 954 | struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete); | 989 | struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete); |
| 955 | void xfrm_policy_flush(void); | 990 | void xfrm_policy_flush(u8 type); |
| 956 | u32 xfrm_get_acqseq(void); | 991 | u32 xfrm_get_acqseq(void); |
| 957 | void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); | 992 | void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); |
| 958 | struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, | 993 | struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, |
| 959 | xfrm_address_t *daddr, xfrm_address_t *saddr, | 994 | xfrm_address_t *daddr, xfrm_address_t *saddr, |
| 960 | int create, unsigned short family); | 995 | int create, unsigned short family); |
| 961 | extern void xfrm_policy_flush(void); | 996 | extern void xfrm_policy_flush(u8 type); |
| 962 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); | 997 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); |
| 963 | extern int xfrm_flush_bundles(void); | 998 | extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family, int strict); |
| 964 | extern void xfrm_flush_all_bundles(void); | ||
| 965 | extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family); | ||
| 966 | extern void xfrm_init_pmtu(struct dst_entry *dst); | 999 | extern void xfrm_init_pmtu(struct dst_entry *dst); |
| 967 | 1000 | ||
| 968 | extern wait_queue_head_t km_waitq; | 1001 | extern wait_queue_head_t km_waitq; |
| 969 | extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport); | 1002 | extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport); |
| 970 | extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid); | 1003 | extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid); |
| 1004 | extern int km_report(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr); | ||
| 971 | 1005 | ||
| 972 | extern void xfrm_input_init(void); | 1006 | extern void xfrm_input_init(void); |
| 973 | extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq); | 1007 | extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq); |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | 27 | ||
| 28 | #include <linux/bitops.h> | 28 | #include <linux/bitops.h> |
| 29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
| 30 | #include <linux/workqueue.h> | ||
| 30 | #include "pcm.h" | 31 | #include "pcm.h" |
| 31 | #include "control.h" | 32 | #include "control.h" |
| 32 | #include "info.h" | 33 | #include "info.h" |
| @@ -140,6 +141,20 @@ · 107 unmodified lines | |||
| 140 | #define AC97_GP_DRSS_1011 0x0000 /* LR(C) 10+11(+12) */ | 141 | #define AC97_GP_DRSS_1011 0x0000 /* LR(C) 10+11(+12) */ |
| 141 | #define AC97_GP_DRSS_78 0x0400 /* LR 7+8 */ | 142 | #define AC97_GP_DRSS_78 0x0400 /* LR 7+8 */ |
| 142 | 143 | ||
| 144 | /* powerdown bits */ | ||
| 145 | #define AC97_PD_ADC_STATUS 0x0001 /* ADC status (RO) */ | ||
| 146 | #define AC97_PD_DAC_STATUS 0x0002 /* DAC status (RO) */ | ||
| 147 | #define AC97_PD_MIXER_STATUS 0x0004 /* Analog mixer status (RO) */ | ||
| 148 | #define AC97_PD_VREF_STATUS 0x0008 /* Vref status (RO) */ | ||
| 149 | #define AC97_PD_PR0 0x0100 /* Power down PCM ADCs and input MUX */ | ||
| 150 | #define AC97_PD_PR1 0x0200 /* Power down PCM front DAC */ | ||
| 151 | #define AC97_PD_PR2 0x0400 /* Power down Mixer (Vref still on) */ | ||
| 152 | #define AC97_PD_PR3 0x0800 /* Power down Mixer (Vref off) */ | ||
| 153 | #define AC97_PD_PR4 0x1000 /* Power down AC-Link */ | ||
| 154 | #define AC97_PD_PR5 0x2000 /* Disable internal clock usage */ | ||
| 155 | #define AC97_PD_PR6 0x4000 /* Headphone amplifier */ | ||
| 156 | #define AC97_PD_EAPD 0x8000 /* External Amplifer Power Down (EAPD) */ | ||
| 157 | |||
| 143 | /* extended audio ID bit defines */ | 158 | /* extended audio ID bit defines */ |
| 144 | #define AC97_EI_VRA 0x0001 /* Variable bit rate supported */ | 159 | #define AC97_EI_VRA 0x0001 /* Variable bit rate supported */ |
| 145 | #define AC97_EI_DRA 0x0002 /* Double rate supported */ | 160 | #define AC97_EI_DRA 0x0002 /* Double rate supported */ |
| @@ -359,6 +374,7 @@ · 213 unmodified lines | |||
| 359 | #define AC97_SCAP_INV_EAPD (1<<7) /* inverted EAPD */ | 374 | #define AC97_SCAP_INV_EAPD (1<<7) /* inverted EAPD */ |
| 360 | #define AC97_SCAP_DETECT_BY_VENDOR (1<<8) /* use vendor registers for read tests */ | 375 | #define AC97_SCAP_DETECT_BY_VENDOR (1<<8) /* use vendor registers for read tests */ |
| 361 | #define AC97_SCAP_NO_SPDIF (1<<9) /* don't build SPDIF controls */ | 376 | #define AC97_SCAP_NO_SPDIF (1<<9) /* don't build SPDIF controls */ |
| 377 | #define AC97_SCAP_EAPD_LED (1<<10) /* EAPD as mute LED */ | ||
| 362 | 378 | ||
| 363 | /* ac97->flags */ | 379 | /* ac97->flags */ |
| 364 | #define AC97_HAS_PC_BEEP (1<<0) /* force PC Speaker usage */ | 380 | #define AC97_HAS_PC_BEEP (1<<0) /* force PC Speaker usage */ |
| @@ -491,6 +507,12 @@ struct snd_ac97 { · 126 unmodified lines | |||
| 491 | /* jack-sharing info */ | 507 | /* jack-sharing info */ |
| 492 | unsigned char indep_surround; | 508 | unsigned char indep_surround; |
| 493 | unsigned char channel_mode; | 509 | unsigned char channel_mode; |
| 510 | |||
| 511 | #ifdef CONFIG_SND_AC97_POWER_SAVE | ||
| 512 | unsigned int power_up; /* power states */ | ||
| 513 | struct workqueue_struct *power_workq; | ||
| 514 | struct work_struct power_work; | ||
| 515 | #endif | ||
| 494 | struct device dev; | 516 | struct device dev; |
| 495 | }; | 517 | }; |
| 496 | 518 | ||
| @@ -532,6 +554,15 @@ unsigned short snd_ac97_read(struct snd_ac97 *ac97, unsigned short reg); · 35 unmodified lines | |||
| 532 | void snd_ac97_write_cache(struct snd_ac97 *ac97, unsigned short reg, unsigned short value); | 554 | void snd_ac97_write_cache(struct snd_ac97 *ac97, unsigned short reg, unsigned short value); |
| 533 | int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short value); | 555 | int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short value); |
| 534 | int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value); | 556 | int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value); |
| 557 | #ifdef CONFIG_SND_AC97_POWER_SAVE | ||
| 558 | int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup); | ||
| 559 | #else | ||
| 560 | static inline int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, | ||
| 561 | int powerup) | ||
| 562 | { | ||
| 563 | return 0; | ||
| 564 | } | ||
| 565 | #endif | ||
| 535 | #ifdef CONFIG_PM | 566 | #ifdef CONFIG_PM |
| 536 | void snd_ac97_suspend(struct snd_ac97 *ac97); | 567 | void snd_ac97_suspend(struct snd_ac97 *ac97); |
| 537 | void snd_ac97_resume(struct snd_ac97 *ac97); | 568 | void snd_ac97_resume(struct snd_ac97 *ac97); |
| @@ -583,6 +614,7 @@ struct ac97_pcm { · 45 unmodified lines | |||
| 583 | copy_flag: 1, /* lowlevel driver must fill all entries */ | 614 | copy_flag: 1, /* lowlevel driver must fill all entries */ |
| 584 | spdif: 1; /* spdif pcm */ | 615 | spdif: 1; /* spdif pcm */ |
| 585 | unsigned short aslots; /* active slots */ | 616 | unsigned short aslots; /* active slots */ |
| 617 | unsigned short cur_dbl; /* current double-rate state */ | ||
| 586 | unsigned int rates; /* available rates */ | 618 | unsigned int rates; /* available rates */ |
| 587 | struct { | 619 | struct { |
| 588 | unsigned short slots; /* driver input: requested AC97 slot numbers */ | 620 | unsigned short slots; /* driver input: requested AC97 slot numbers */ |
| @@ -179,14 +179,13 @@ enum { AD1848_MIX_SINGLE, AD1848_MIX_DOUBLE, AD1848_MIX_CAPTURE }; · 178 unmodified lines | |||
| 179 | #define AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) \ | 179 | #define AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) \ |
| 180 | ((left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22)) | 180 | ((left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22)) |
| 181 | 181 | ||
| 182 | int snd_ad1848_add_ctl(struct snd_ad1848 *chip, const char *name, int index, int type, unsigned long value); | ||
| 183 | |||
| 184 | /* for ease of use */ | 182 | /* for ease of use */ |
| 185 | struct ad1848_mix_elem { | 183 | struct ad1848_mix_elem { |
| 186 | const char *name; | 184 | const char *name; |
| 187 | int index; | 185 | int index; |
| 188 | int type; | 186 | int type; |
| 189 | unsigned long private_value; | 187 | unsigned long private_value; |
| 188 | unsigned int *tlv; | ||
| 190 | }; | 189 | }; |
| 191 | 190 | ||
| 192 | #define AD1848_SINGLE(xname, xindex, reg, shift, mask, invert) \ | 191 | #define AD1848_SINGLE(xname, xindex, reg, shift, mask, invert) \ |
| @@ -195,15 +194,26 @@ struct ad1848_mix_elem { · 2 unmodified lines | |||
| 195 | .type = AD1848_MIX_SINGLE, \ | 194 | .type = AD1848_MIX_SINGLE, \ |
| 196 | .private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) } | 195 | .private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) } |
| 197 | 196 | ||
| 197 | #define AD1848_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \ | ||
| 198 | { .name = xname, \ | ||
| 199 | .index = xindex, \ | ||
| 200 | .type = AD1848_MIX_SINGLE, \ | ||
| 201 | .private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert), \ | ||
| 202 | .tlv = xtlv } | ||
| 203 | |||
| 198 | #define AD1848_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \ | 204 | #define AD1848_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \ |
| 199 | { .name = xname, \ | 205 | { .name = xname, \ |
| 200 | .index = xindex, \ | 206 | .index = xindex, \ |
| 201 | .type = AD1848_MIX_DOUBLE, \ | 207 | .type = AD1848_MIX_DOUBLE, \ |
| 202 | .private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) } | 208 | .private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) } |
| 203 | 209 | ||
| 204 | static inline int snd_ad1848_add_ctl_elem(struct snd_ad1848 *chip, const struct ad1848_mix_elem *c) | 210 | #define AD1848_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \ |
| 205 | { | 211 | { .name = xname, \ |
| 206 | return snd_ad1848_add_ctl(chip, c->name, c->index, c->type, c->private_value); | 212 | .index = xindex, \ |
| 207 | } | 213 | .type = AD1848_MIX_DOUBLE, \ |
| 214 | .private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert), \ | ||
| 215 | .tlv = xtlv } | ||
| 216 | |||
| 217 | int snd_ad1848_add_ctl_elem(struct snd_ad1848 *chip, const struct ad1848_mix_elem *c); | ||
| 208 | 218 | ||
| 209 | #endif /* __SOUND_AD1848_H */ | 219 | #endif /* __SOUND_AD1848_H */ |
| @@ -39,26 +39,39 @@ struct snd_ak4xxx_ops { · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | #define AK4XXX_IMAGE_SIZE (AK4XXX_MAX_CHIPS * 16) /* 64 bytes */ | 40 | #define AK4XXX_IMAGE_SIZE (AK4XXX_MAX_CHIPS * 16) /* 64 bytes */ |
| 41 | 41 | ||
| 42 | /* DAC label and channels */ | ||
| 43 | struct snd_akm4xxx_dac_channel { | ||
| 44 | char *name; /* mixer volume name */ | ||
| 45 | unsigned int num_channels; | ||
| 46 | }; | ||
| 47 | |||
| 48 | /* ADC labels and channels */ | ||
| 49 | struct snd_akm4xxx_adc_channel { | ||
| 50 | char *name; /* capture gain volume label */ | ||
| 51 | char *switch_name; /* capture switch */ | ||
| 52 | unsigned int num_channels; | ||
| 53 | }; | ||
| 54 | |||
| 42 | struct snd_akm4xxx { | 55 | struct snd_akm4xxx { |
| 43 | struct snd_card *card; | 56 | struct snd_card *card; |
| 44 | unsigned int num_adcs; /* AK4524 or AK4528 ADCs */ | 57 | unsigned int num_adcs; /* AK4524 or AK4528 ADCs */ |
| 45 | unsigned int num_dacs; /* AK4524 or AK4528 DACs */ | 58 | unsigned int num_dacs; /* AK4524 or AK4528 DACs */ |
| 46 | unsigned char images[AK4XXX_IMAGE_SIZE]; /* saved register image */ | 59 | unsigned char images[AK4XXX_IMAGE_SIZE]; /* saved register image */ |
| 47 | unsigned char ipga_gain[AK4XXX_MAX_CHIPS][2]; /* saved register image | 60 | unsigned char volumes[AK4XXX_IMAGE_SIZE]; /* saved volume values */ |
| 48 | * for IPGA (AK4528) | ||
| 49 | */ | ||
| 50 | unsigned long private_value[AK4XXX_MAX_CHIPS]; /* helper for driver */ | 61 | unsigned long private_value[AK4XXX_MAX_CHIPS]; /* helper for driver */ |
| 51 | void *private_data[AK4XXX_MAX_CHIPS]; /* helper for driver */ | 62 | void *private_data[AK4XXX_MAX_CHIPS]; /* helper for driver */ |
| 52 | /* template should fill the following fields */ | 63 | /* template should fill the following fields */ |
| 53 | unsigned int idx_offset; /* control index offset */ | 64 | unsigned int idx_offset; /* control index offset */ |
| 54 | enum { | 65 | enum { |
| 55 | SND_AK4524, SND_AK4528, SND_AK4529, | 66 | SND_AK4524, SND_AK4528, SND_AK4529, |
| 56 | SND_AK4355, SND_AK4358, SND_AK4381 | 67 | SND_AK4355, SND_AK4358, SND_AK4381, |
| 68 | SND_AK5365 | ||
| 57 | } type; | 69 | } type; |
| 58 | unsigned int *num_stereo; /* array of combined counts | 70 | |
| 59 | * for the mixer | 71 | /* (array) information of combined codecs */ |
| 60 | */ | 72 | struct snd_akm4xxx_dac_channel *dac_info; |
| 61 | char **channel_names; /* array of mixer channel names */ | 73 | struct snd_akm4xxx_adc_channel *adc_info; |
| 74 | |||
| 62 | struct snd_ak4xxx_ops ops; | 75 | struct snd_ak4xxx_ops ops; |
| 63 | }; | 76 | }; |
| 64 | 77 | ||
| @@ -72,9 +85,9 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak); · 7 unmodified lines | |||
| 72 | (ak)->images[(chip) * 16 + (reg)] | 85 | (ak)->images[(chip) * 16 + (reg)] |
| 73 | #define snd_akm4xxx_set(ak,chip,reg,val) \ | 86 | #define snd_akm4xxx_set(ak,chip,reg,val) \ |
| 74 | ((ak)->images[(chip) * 16 + (reg)] = (val)) | 87 | ((ak)->images[(chip) * 16 + (reg)] = (val)) |
| 75 | #define snd_akm4xxx_get_ipga(ak,chip,reg) \ | 88 | #define snd_akm4xxx_get_vol(ak,chip,reg) \ |
| 76 | (ak)->ipga_gain[chip][(reg)-4] | 89 | (ak)->volumes[(chip) * 16 + (reg)] |
| 77 | #define snd_akm4xxx_set_ipga(ak,chip,reg,val) \ | 90 | #define snd_akm4xxx_set_vol(ak,chip,reg,val) \ |
| 78 | ((ak)->ipga_gain[chip][(reg)-4] = (val)) | 91 | ((ak)->volumes[(chip) * 16 + (reg)] = (val)) |
| 79 | 92 | ||
| 80 | #endif /* __SOUND_AK4XXX_ADDA_H */ | 93 | #endif /* __SOUND_AK4XXX_ADDA_H */ |
| @@ -688,7 +688,7 @@ struct snd_timer_tread { · 687 unmodified lines | |||
| 688 | * * | 688 | * * |
| 689 | ****************************************************************************/ | 689 | ****************************************************************************/ |
| 690 | 690 | ||
| 691 | #define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 3) | 691 | #define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 4) |
| 692 | 692 | ||
| 693 | struct snd_ctl_card_info { | 693 | struct snd_ctl_card_info { |
| 694 | int card; /* card number */ | 694 | int card; /* card number */ |
| @@ -727,10 +727,15 @@ typedef int __bitwise snd_ctl_elem_iface_t; · 32 unmodified lines | |||
| 727 | #define SNDRV_CTL_ELEM_ACCESS_WRITE (1<<1) | 727 | #define SNDRV_CTL_ELEM_ACCESS_WRITE (1<<1) |
| 728 | #define SNDRV_CTL_ELEM_ACCESS_READWRITE (SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE) | 728 | #define SNDRV_CTL_ELEM_ACCESS_READWRITE (SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE) |
| 729 | #define SNDRV_CTL_ELEM_ACCESS_VOLATILE (1<<2) /* control value may be changed without a notification */ | 729 | #define SNDRV_CTL_ELEM_ACCESS_VOLATILE (1<<2) /* control value may be changed without a notification */ |
| 730 | #define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP (1<<2) /* when was control changed */ | 730 | #define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP (1<<3) /* when was control changed */ |
| 731 | #define SNDRV_CTL_ELEM_ACCESS_TLV_READ (1<<4) /* TLV read is possible */ | ||
| 732 | #define SNDRV_CTL_ELEM_ACCESS_TLV_WRITE (1<<5) /* TLV write is possible */ | ||
| 733 | #define SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE (SNDRV_CTL_ELEM_ACCESS_TLV_READ|SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) | ||
| 734 | #define SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND (1<<6) /* TLV command is possible */ | ||
| 731 | #define SNDRV_CTL_ELEM_ACCESS_INACTIVE (1<<8) /* control does actually nothing, but may be updated */ | 735 | #define SNDRV_CTL_ELEM_ACCESS_INACTIVE (1<<8) /* control does actually nothing, but may be updated */ |
| 732 | #define SNDRV_CTL_ELEM_ACCESS_LOCK (1<<9) /* write lock */ | 736 | #define SNDRV_CTL_ELEM_ACCESS_LOCK (1<<9) /* write lock */ |
| 733 | #define SNDRV_CTL_ELEM_ACCESS_OWNER (1<<10) /* write lock owner */ | 737 | #define SNDRV_CTL_ELEM_ACCESS_OWNER (1<<10) /* write lock owner */ |
| 738 | #define SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK (1<<28) /* kernel use a TLV callback */ | ||
| 734 | #define SNDRV_CTL_ELEM_ACCESS_USER (1<<29) /* user space element */ | 739 | #define SNDRV_CTL_ELEM_ACCESS_USER (1<<29) /* user space element */ |
| 735 | #define SNDRV_CTL_ELEM_ACCESS_DINDIRECT (1<<30) /* indirect access for matrix dimensions in the info structure */ | 740 | #define SNDRV_CTL_ELEM_ACCESS_DINDIRECT (1<<30) /* indirect access for matrix dimensions in the info structure */ |
| 736 | #define SNDRV_CTL_ELEM_ACCESS_INDIRECT (1<<31) /* indirect access for element value in the value structure */ | 741 | #define SNDRV_CTL_ELEM_ACCESS_INDIRECT (1<<31) /* indirect access for element value in the value structure */ |
| @@ -818,6 +823,12 @@ struct snd_ctl_elem_value { · 81 unmodified lines | |||
| 818 | unsigned char reserved[128-sizeof(struct timespec)]; | 823 | unsigned char reserved[128-sizeof(struct timespec)]; |
| 819 | }; | 824 | }; |
| 820 | 825 | ||
| 826 | struct snd_ctl_tlv { | ||
| 827 | unsigned int numid; /* control element numeric identification */ | ||
| 828 | unsigned int length; /* in bytes aligned to 4 */ | ||
| 829 | unsigned int tlv[0]; /* first TLV */ | ||
| 830 | }; | ||
| 831 | |||
| 821 | enum { | 832 | enum { |
| 822 | SNDRV_CTL_IOCTL_PVERSION = _IOR('U', 0x00, int), | 833 | SNDRV_CTL_IOCTL_PVERSION = _IOR('U', 0x00, int), |
| 823 | SNDRV_CTL_IOCTL_CARD_INFO = _IOR('U', 0x01, struct snd_ctl_card_info), | 834 | SNDRV_CTL_IOCTL_CARD_INFO = _IOR('U', 0x01, struct snd_ctl_card_info), |
| @@ -831,6 +842,9 @@ enum { · 7 unmodified lines | |||
| 831 | SNDRV_CTL_IOCTL_ELEM_ADD = _IOWR('U', 0x17, struct snd_ctl_elem_info), | 842 | SNDRV_CTL_IOCTL_ELEM_ADD = _IOWR('U', 0x17, struct snd_ctl_elem_info), |
| 832 | SNDRV_CTL_IOCTL_ELEM_REPLACE = _IOWR('U', 0x18, struct snd_ctl_elem_info), | 843 | SNDRV_CTL_IOCTL_ELEM_REPLACE = _IOWR('U', 0x18, struct snd_ctl_elem_info), |
| 833 | SNDRV_CTL_IOCTL_ELEM_REMOVE = _IOWR('U', 0x19, struct snd_ctl_elem_id), | 844 | SNDRV_CTL_IOCTL_ELEM_REMOVE = _IOWR('U', 0x19, struct snd_ctl_elem_id), |
| 845 | SNDRV_CTL_IOCTL_TLV_READ = _IOWR('U', 0x1a, struct snd_ctl_tlv), | ||
| 846 | SNDRV_CTL_IOCTL_TLV_WRITE = _IOWR('U', 0x1b, struct snd_ctl_tlv), | ||
| 847 | SNDRV_CTL_IOCTL_TLV_COMMAND = _IOWR('U', 0x1c, struct snd_ctl_tlv), | ||
| 834 | SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE = _IOWR('U', 0x20, int), | 848 | SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE = _IOWR('U', 0x20, int), |
| 835 | SNDRV_CTL_IOCTL_HWDEP_INFO = _IOR('U', 0x21, struct snd_hwdep_info), | 849 | SNDRV_CTL_IOCTL_HWDEP_INFO = _IOR('U', 0x21, struct snd_hwdep_info), |
| 836 | SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE = _IOR('U', 0x30, int), | 850 | SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE = _IOR('U', 0x30, int), |
| @@ -855,6 +869,7 @@ enum sndrv_ctl_event_type { · 18 unmodified lines | |||
| 855 | #define SNDRV_CTL_EVENT_MASK_VALUE (1<<0) /* element value was changed */ | 869 | #define SNDRV_CTL_EVENT_MASK_VALUE (1<<0) /* element value was changed */ |
| 856 | #define SNDRV_CTL_EVENT_MASK_INFO (1<<1) /* element info was changed */ | 870 | #define SNDRV_CTL_EVENT_MASK_INFO (1<<1) /* element info was changed */ |
| 857 | #define SNDRV_CTL_EVENT_MASK_ADD (1<<2) /* element was added */ | 871 | #define SNDRV_CTL_EVENT_MASK_ADD (1<<2) /* element was added */ |
| 872 | #define SNDRV_CTL_EVENT_MASK_TLV (1<<3) /* element TLV tree was changed */ | ||
| 858 | #define SNDRV_CTL_EVENT_MASK_REMOVE (~0U) /* element was removed */ | 873 | #define SNDRV_CTL_EVENT_MASK_REMOVE (~0U) /* element was removed */ |
| 859 | 874 | ||
| 860 | struct snd_ctl_event { | 875 | struct snd_ctl_event { |
| @@ -30,6 +30,11 @@ struct snd_kcontrol; · 29 unmodified lines | |||
| 30 | typedef int (snd_kcontrol_info_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_info * uinfo); | 30 | typedef int (snd_kcontrol_info_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_info * uinfo); |
| 31 | typedef int (snd_kcontrol_get_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol); | 31 | typedef int (snd_kcontrol_get_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol); |
| 32 | typedef int (snd_kcontrol_put_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol); | 32 | typedef int (snd_kcontrol_put_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol); |
| 33 | typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol, | ||
| 34 | int op_flag, /* 0=read,1=write,-1=command */ | ||
| 35 | unsigned int size, | ||
| 36 | unsigned int __user *tlv); | ||
| 37 | |||
| 33 | 38 | ||
| 34 | struct snd_kcontrol_new { | 39 | struct snd_kcontrol_new { |
| 35 | snd_ctl_elem_iface_t iface; /* interface identifier */ | 40 | snd_ctl_elem_iface_t iface; /* interface identifier */ |
| @@ -42,6 +47,10 @@ struct snd_kcontrol_new { · 6 unmodified lines | |||
| 42 | snd_kcontrol_info_t *info; | 47 | snd_kcontrol_info_t *info; |
| 43 | snd_kcontrol_get_t *get; | 48 | snd_kcontrol_get_t *get; |
| 44 | snd_kcontrol_put_t *put; | 49 | snd_kcontrol_put_t *put; |
| 50 | union { | ||
| 51 | snd_kcontrol_tlv_rw_t *c; | ||
| 52 | unsigned int *p; | ||
| 53 | } tlv; | ||
| 45 | unsigned long private_value; | 54 | unsigned long private_value; |
| 46 | }; | 55 | }; |
| 47 | 56 | ||
| @@ -58,6 +67,10 @@ struct snd_kcontrol { · 10 unmodified lines | |||
| 58 | snd_kcontrol_info_t *info; | 67 | snd_kcontrol_info_t *info; |
| 59 | snd_kcontrol_get_t *get; | 68 | snd_kcontrol_get_t *get; |
| 60 | snd_kcontrol_put_t *put; | 69 | snd_kcontrol_put_t *put; |
| 70 | union { | ||
| 71 | snd_kcontrol_tlv_rw_t *c; | ||
| 72 | unsigned int *p; | ||
| 73 | } tlv; | ||
| 61 | unsigned long private_value; | 74 | unsigned long private_value; |
| 62 | void *private_data; | 75 | void *private_data; |
| 63 | void (*private_free)(struct snd_kcontrol *kcontrol); | 76 | void (*private_free)(struct snd_kcontrol *kcontrol); |
| @@ -25,8 +25,8 @@ · 24 unmodified lines | |||
| 25 | #include <linux/sched.h> /* wake_up() */ | 25 | #include <linux/sched.h> /* wake_up() */ |
| 26 | #include <linux/mutex.h> /* struct mutex */ | 26 | #include <linux/mutex.h> /* struct mutex */ |
| 27 | #include <linux/rwsem.h> /* struct rw_semaphore */ | 27 | #include <linux/rwsem.h> /* struct rw_semaphore */ |
| 28 | #include <linux/workqueue.h> /* struct workqueue_struct */ | ||
| 29 | #include <linux/pm.h> /* pm_message_t */ | 28 | #include <linux/pm.h> /* pm_message_t */ |
| 29 | #include <linux/device.h> | ||
| 30 | 30 | ||
| 31 | /* forward declarations */ | 31 | /* forward declarations */ |
| 32 | #ifdef CONFIG_PCI | 32 | #ifdef CONFIG_PCI |
| @@ -71,7 +71,6 @@ struct snd_device_ops { · 38 unmodified lines | |||
| 71 | int (*dev_free)(struct snd_device *dev); | 71 | int (*dev_free)(struct snd_device *dev); |
| 72 | int (*dev_register)(struct snd_device *dev); | 72 | int (*dev_register)(struct snd_device *dev); |
| 73 | int (*dev_disconnect)(struct snd_device *dev); | 73 | int (*dev_disconnect)(struct snd_device *dev); |
| 74 | int (*dev_unregister)(struct snd_device *dev); | ||
| 75 | }; | 74 | }; |
| 76 | 75 | ||
| 77 | struct snd_device { | 76 | struct snd_device { |
| @@ -131,8 +130,8 @@ struct snd_card { · 53 unmodified lines | |||
| 131 | state */ | 130 | state */ |
| 132 | spinlock_t files_lock; /* lock the files for this card */ | 131 | spinlock_t files_lock; /* lock the files for this card */ |
| 133 | int shutdown; /* this card is going down */ | 132 | int shutdown; /* this card is going down */ |
| 133 | int free_on_last_close; /* free in context of file_release */ | ||
| 134 | wait_queue_head_t shutdown_sleep; | 134 | wait_queue_head_t shutdown_sleep; |
| 135 | struct work_struct free_workq; /* for free in workqueue */ | ||
| 136 | struct device *dev; | 135 | struct device *dev; |
| 137 | 136 | ||
| 138 | #ifdef CONFIG_PM | 137 | #ifdef CONFIG_PM |
| @@ -188,6 +187,7 @@ struct snd_minor { · 49 unmodified lines | |||
| 188 | int device; /* device number */ | 187 | int device; /* device number */ |
| 189 | const struct file_operations *f_ops; /* file operations */ | 188 | const struct file_operations *f_ops; /* file operations */ |
| 190 | void *private_data; /* private data for f_ops->open */ | 189 | void *private_data; /* private data for f_ops->open */ |
| 190 | struct class_device *class_dev; /* class device for sysfs */ | ||
| 191 | }; | 191 | }; |
| 192 | 192 | ||
| 193 | /* sound.c */ | 193 | /* sound.c */ |
| @@ -202,6 +202,8 @@ int snd_register_device(int type, struct snd_card *card, int dev, · 8 unmodified lines | |||
| 202 | const char *name); | 202 | const char *name); |
| 203 | int snd_unregister_device(int type, struct snd_card *card, int dev); | 203 | int snd_unregister_device(int type, struct snd_card *card, int dev); |
| 204 | void *snd_lookup_minor_data(unsigned int minor, int type); | 204 | void *snd_lookup_minor_data(unsigned int minor, int type); |
| 205 | int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev, | ||
| 206 | const struct class_device_attribute *attr); | ||
| 205 | 207 | ||
| 206 | #ifdef CONFIG_SND_OSSEMUL | 208 | #ifdef CONFIG_SND_OSSEMUL |
| 207 | int snd_register_oss_device(int type, struct snd_card *card, int dev, | 209 | int snd_register_oss_device(int type, struct snd_card *card, int dev, |
| @@ -244,7 +246,7 @@ struct snd_card *snd_card_new(int idx, const char *id, · 36 unmodified lines | |||
| 244 | struct module *module, int extra_size); | 246 | struct module *module, int extra_size); |
| 245 | int snd_card_disconnect(struct snd_card *card); | 247 | int snd_card_disconnect(struct snd_card *card); |
| 246 | int snd_card_free(struct snd_card *card); | 248 | int snd_card_free(struct snd_card *card); |
| 247 | int snd_card_free_in_thread(struct snd_card *card); | 249 | int snd_card_free_when_closed(struct snd_card *card); |
| 248 | int snd_card_register(struct snd_card *card); | 250 | int snd_card_register(struct snd_card *card); |
| 249 | int snd_card_info_init(void); | 251 | int snd_card_info_init(void); |
| 250 | int snd_card_info_done(void); | 252 | int snd_card_info_done(void); |
| @@ -1524,6 +1524,10 @@ struct snd_emu10k1_fx8010_control_gpr { · 1523 unmodified lines | |||
| 1524 | unsigned int value[32]; /* initial values */ | 1524 | unsigned int value[32]; /* initial values */ |
| 1525 | unsigned int min; /* minimum range */ | 1525 | unsigned int min; /* minimum range */ |
| 1526 | unsigned int max; /* maximum range */ | 1526 | unsigned int max; /* maximum range */ |
| 1527 | union { | ||
| 1528 | snd_kcontrol_tlv_rw_t *c; | ||
| 1529 | unsigned int *p; | ||
| 1530 | } tlv; | ||
| 1527 | unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ | 1531 | unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ |
| 1528 | }; | 1532 | }; |
| 1529 | 1533 | ||
| @@ -71,7 +71,6 @@ struct snd_info_entry { · 70 unmodified lines | |||
| 71 | mode_t mode; | 71 | mode_t mode; |
| 72 | long size; | 72 | long size; |
| 73 | unsigned short content; | 73 | unsigned short content; |
| 74 | unsigned short disconnected: 1; | ||
| 75 | union { | 74 | union { |
| 76 | struct snd_info_entry_text text; | 75 | struct snd_info_entry_text text; |
| 77 | struct snd_info_entry_ops *ops; | 76 | struct snd_info_entry_ops *ops; |
| @@ -83,6 +82,8 @@ struct snd_info_entry { · 5 unmodified lines | |||
| 83 | void (*private_free)(struct snd_info_entry *entry); | 82 | void (*private_free)(struct snd_info_entry *entry); |
| 84 | struct proc_dir_entry *p; | 83 | struct proc_dir_entry *p; |
| 85 | struct mutex access; | 84 | struct mutex access; |
| 85 | struct list_head children; | ||
| 86 | struct list_head list; | ||
| 86 | }; | 87 | }; |
| 87 | 88 | ||
| 88 | #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS) | 89 | #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS) |
| @@ -122,8 +123,8 @@ int snd_info_restore_text(struct snd_info_entry * entry); · 33 unmodified lines | |||
| 122 | int snd_info_card_create(struct snd_card * card); | 123 | int snd_info_card_create(struct snd_card * card); |
| 123 | int snd_info_card_register(struct snd_card * card); | 124 | int snd_info_card_register(struct snd_card * card); |
| 124 | int snd_info_card_free(struct snd_card * card); | 125 | int snd_info_card_free(struct snd_card * card); |
| 126 | void snd_info_card_disconnect(struct snd_card * card); | ||
| 125 | int snd_info_register(struct snd_info_entry * entry); | 127 | int snd_info_register(struct snd_info_entry * entry); |
| 126 | int snd_info_unregister(struct snd_info_entry * entry); | ||
| 127 | 128 | ||
| 128 | /* for card drivers */ | 129 | /* for card drivers */ |
| 129 | int snd_card_proc_new(struct snd_card *card, const char *name, struct snd_info_entry **entryp); | 130 | int snd_card_proc_new(struct snd_card *card, const char *name, struct snd_info_entry **entryp); |
| @@ -156,8 +157,8 @@ static inline void snd_info_free_entry(struct snd_info_entry * entry) { ; } · 26 unmodified lines | |||
| 156 | static inline int snd_info_card_create(struct snd_card * card) { return 0; } | 157 | static inline int snd_info_card_create(struct snd_card * card) { return 0; } |
| 157 | static inline int snd_info_card_register(struct snd_card * card) { return 0; } | 158 | static inline int snd_info_card_register(struct snd_card * card) { return 0; } |
| 158 | static inline int snd_info_card_free(struct snd_card * card) { return 0; } | 159 | static inline int snd_info_card_free(struct snd_card * card) { return 0; } |
| 160 | static inline void snd_info_card_disconnect(struct snd_card * card) { } | ||
| 159 | static inline int snd_info_register(struct snd_info_entry * entry) { return 0; } | 161 | static inline int snd_info_register(struct snd_info_entry * entry) { return 0; } |
| 160 | static inline int snd_info_unregister(struct snd_info_entry * entry) { return 0; } | ||
| 161 | 162 | ||
| 162 | static inline int snd_card_proc_new(struct snd_card *card, const char *name, | 163 | static inline int snd_card_proc_new(struct snd_card *card, const char *name, |
| 163 | struct snd_info_entry **entryp) { return -EINVAL; } | 164 | struct snd_info_entry **entryp) { return -EINVAL; } |
| @@ -190,7 +190,7 @@ struct snd_pcm_ops { · 189 unmodified lines | |||
| 190 | 190 | ||
| 191 | struct snd_pcm_file { | 191 | struct snd_pcm_file { |
| 192 | struct snd_pcm_substream *substream; | 192 | struct snd_pcm_substream *substream; |
| 193 | struct snd_pcm_file *next; | 193 | int no_compat_mmap; |
| 194 | }; | 194 | }; |
| 195 | 195 | ||
| 196 | struct snd_pcm_hw_rule; | 196 | struct snd_pcm_hw_rule; |
| @@ -384,7 +384,6 @@ struct snd_pcm_substream { · 187 unmodified lines | |||
| 384 | struct snd_info_entry *proc_prealloc_entry; | 384 | struct snd_info_entry *proc_prealloc_entry; |
| 385 | #endif | 385 | #endif |
| 386 | /* misc flags */ | 386 | /* misc flags */ |
| 387 | unsigned int no_mmap_ctrl: 1; | ||
| 388 | unsigned int hw_opened: 1; | 387 | unsigned int hw_opened: 1; |
| 389 | }; | 388 | }; |
| 390 | 389 | ||
| @@ -402,7 +401,6 @@ struct snd_pcm_str { · 11 unmodified lines | |||
| 402 | /* -- OSS things -- */ | 401 | /* -- OSS things -- */ |
| 403 | struct snd_pcm_oss_stream oss; | 402 | struct snd_pcm_oss_stream oss; |
| 404 | #endif | 403 | #endif |
| 405 | struct snd_pcm_file *files; | ||
| 406 | #ifdef CONFIG_SND_VERBOSE_PROCFS | 404 | #ifdef CONFIG_SND_VERBOSE_PROCFS |
| 407 | struct snd_info_entry *proc_root; | 405 | struct snd_info_entry *proc_root; |
| 408 | struct snd_info_entry *proc_info_entry; | 406 | struct snd_info_entry *proc_info_entry; |
| @@ -129,7 +129,6 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam · 128 unmodified lines | |||
| 129 | int snd_timer_global_new(char *id, int device, struct snd_timer **rtimer); | 129 | int snd_timer_global_new(char *id, int device, struct snd_timer **rtimer); |
| 130 | int snd_timer_global_free(struct snd_timer *timer); | 130 | int snd_timer_global_free(struct snd_timer *timer); |
| 131 | int snd_timer_global_register(struct snd_timer *timer); | 131 | int snd_timer_global_register(struct snd_timer *timer); |
| 132 | int snd_timer_global_unregister(struct snd_timer *timer); | ||
| 133 | 132 | ||
| 134 | int snd_timer_open(struct snd_timer_instance **ti, char *owner, struct snd_timer_id *tid, unsigned int slave_id); | 133 | int snd_timer_open(struct snd_timer_instance **ti, char *owner, struct snd_timer_id *tid, unsigned int slave_id); |
| 135 | int snd_timer_close(struct snd_timer_instance *timeri); | 134 | int snd_timer_close(struct snd_timer_instance *timeri); |
| @@ -0,0 +1,60 @@ | |||
| 1 | #ifndef __SOUND_TLV_H | ||
| 2 | #define __SOUND_TLV_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Advanced Linux Sound Architecture - ALSA - Driver | ||
| 6 | * Copyright (c) 2006 by Jaroslav Kysela <perex@suse.cz> | ||
| 7 | * | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 22 | * | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * TLV structure is right behind the struct snd_ctl_tlv: | ||
| 27 | * unsigned int type - see SNDRV_CTL_TLVT_* | ||
| 28 | * unsigned int length | ||
| 29 | * .... data aligned to sizeof(unsigned int), use | ||
| 30 | * block_length = (length + (sizeof(unsigned int) - 1)) & | ||
| 31 | * ~(sizeof(unsigned int) - 1)) .... | ||
| 32 | */ | ||
| 33 | |||
| 34 | #define SNDRV_CTL_TLVT_CONTAINER 0 /* one level down - group of TLVs */ | ||
| 35 | #define SNDRV_CTL_TLVT_DB_SCALE 1 /* dB scale */ | ||
| 36 | #define SNDRV_CTL_TLVT_DB_LINEAR 2 /* linear volume */ | ||
| 37 | #define SNDRV_CTL_TLVT_DB_RANGE 3 /* dB range container */ | ||
| 38 | |||
| 39 | #define TLV_DB_SCALE_ITEM(min, step, mute) \ | ||
| 40 | SNDRV_CTL_TLVT_DB_SCALE, 2 * sizeof(unsigned int), \ | ||
| 41 | (min), ((step) & 0xffff) | ((mute) ? 0x10000 : 0) | ||
| 42 | #define DECLARE_TLV_DB_SCALE(name, min, step, mute) \ | ||
| 43 | unsigned int name[] = { TLV_DB_SCALE_ITEM(min, step, mute) } | ||
| 44 | |||
| 45 | /* linear volume between min_dB and max_dB (.01dB unit) */ | ||
| 46 | #define TLV_DB_LINEAR_ITEM(min_dB, max_dB) \ | ||
| 47 | SNDRV_CTL_TLVT_DB_LINEAR, 2 * sizeof(unsigned int), \ | ||
| 48 | (min_dB), (max_dB) | ||
| 49 | #define DECLARE_TLV_DB_LINEAR(name, min_dB, max_dB) \ | ||
| 50 | unsigned int name[] = { TLV_DB_LINEAR_ITEM(min_dB, max_dB) } | ||
| 51 | |||
| 52 | /* dB range container */ | ||
| 53 | /* Each item is: <min> <max> <TLV> */ | ||
| 54 | /* The below assumes that each item TLV is 4 words like DB_SCALE or LINEAR */ | ||
| 55 | #define TLV_DB_RANGE_HEAD(num) \ | ||
| 56 | SNDRV_CTL_TLVT_DB_RANGE, 6 * (num) * sizeof(unsigned int) | ||
| 57 | |||
| 58 | #define TLV_DB_GAIN_MUTE -9999999 | ||
| 59 | |||
| 60 | #endif /* __SOUND_TLV_H */ | ||
| @@ -128,6 +128,7 @@ struct snd_vx_hardware { · 127 unmodified lines | |||
| 128 | unsigned int num_ins; | 128 | unsigned int num_ins; |
| 129 | unsigned int num_outs; | 129 | unsigned int num_outs; |
| 130 | unsigned int output_level_max; | 130 | unsigned int output_level_max; |
| 131 | unsigned int *output_level_db_scale; | ||
| 131 | }; | 132 | }; |
| 132 | 133 | ||
| 133 | /* hwdep id string */ | 134 | /* hwdep id string */ |
| @@ -75,7 +75,7 @@ static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp, · 74 unmodified lines | |||
| 75 | /* | 75 | /* |
| 76 | * If new attributes are added, please revisit this allocation | 76 | * If new attributes are added, please revisit this allocation |
| 77 | */ | 77 | */ |
| 78 | skb = nlmsg_new(size); | 78 | skb = nlmsg_new(size, GFP_KERNEL); |
| 79 | if (!skb) | 79 | if (!skb) |
| 80 | return -ENOMEM; | 80 | return -ENOMEM; |
| 81 | 81 | ||
| @@ -802,6 +802,15 @@ int test_set_page_writeback(struct page *page) · 801 unmodified lines | |||
| 802 | } | 802 | } |
| 803 | EXPORT_SYMBOL(test_set_page_writeback); | 803 | EXPORT_SYMBOL(test_set_page_writeback); |
| 804 | 804 | ||
| 805 | /* | ||
| 806 | * Wakes up tasks that are being throttled due to writeback congestion | ||
| 807 | */ | ||
| 808 | void writeback_congestion_end(void) | ||
| 809 | { | ||
| 810 | blk_congestion_end(WRITE); | ||
| 811 | } | ||
| 812 | EXPORT_SYMBOL(writeback_congestion_end); | ||
| 813 | |||
| 805 | /* | 814 | /* |
| 806 | * Return true if any of the pages in the mapping are marged with the | 815 | * Return true if any of the pages in the mapping are marged with the |
| 807 | * passed tag. | 816 | * passed tag. |
| @@ -2363,7 +2363,7 @@ int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write, · 2362 unmodified lines | |||
| 2363 | return 0; | 2363 | return 0; |
| 2364 | } | 2364 | } |
| 2365 | 2365 | ||
| 2366 | __initdata int hashdist = HASHDIST_DEFAULT; | 2366 | int hashdist = HASHDIST_DEFAULT; |
| 2367 | 2367 | ||
| 2368 | #ifdef CONFIG_NUMA | 2368 | #ifdef CONFIG_NUMA |
| 2369 | static int __init set_hashdist(char *str) | 2369 | static int __init set_hashdist(char *str) |
| @@ -249,6 +249,11 @@ source "net/ieee80211/Kconfig" · 248 unmodified lines | |||
| 249 | config WIRELESS_EXT | 249 | config WIRELESS_EXT |
| 250 | bool | 250 | bool |
| 251 | 251 | ||
| 252 | source "net/netlabel/Kconfig" | ||
| 253 | |||
| 254 | config FIB_RULES | ||
| 255 | bool | ||
| 256 | |||
| 252 | endif # if NET | 257 | endif # if NET |
| 253 | endmenu # Networking | 258 | endmenu # Networking |
| 254 | 259 | ||
| @@ -46,6 +46,7 @@ obj-$(CONFIG_IP_DCCP) += dccp/ · 45 unmodified lines | |||
| 46 | obj-$(CONFIG_IP_SCTP) += sctp/ | 46 | obj-$(CONFIG_IP_SCTP) += sctp/ |
| 47 | obj-$(CONFIG_IEEE80211) += ieee80211/ | 47 | obj-$(CONFIG_IEEE80211) += ieee80211/ |
| 48 | obj-$(CONFIG_TIPC) += tipc/ | 48 | obj-$(CONFIG_TIPC) += tipc/ |
| 49 | obj-$(CONFIG_NETLABEL) += netlabel/ | ||
| 49 | 50 | ||
| 50 | ifeq ($(CONFIG_NET),y) | 51 | ifeq ($(CONFIG_NET),y) |
| 51 | obj-$(CONFIG_SYSCTL) += sysctl_net.o | 52 | obj-$(CONFIG_SYSCTL) += sysctl_net.o |
| @@ -1,6 +1,5 @@ | |||
| 1 | /* ATM driver model support. */ | 1 | /* ATM driver model support. */ |
| 2 | 2 | ||
| 3 | #include <linux/config.h> | ||
| 4 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
| 5 | #include <linux/init.h> | 4 | #include <linux/init.h> |
| 6 | #include <linux/kobject.h> | 5 | #include <linux/kobject.h> |
| @@ -98,11 +98,6 @@ static struct notifier_block mpoa_notifier = { · 97 unmodified lines | |||
| 98 | 0 | 98 | 0 |
| 99 | }; | 99 | }; |
| 100 | 100 | ||
| 101 | #ifdef CONFIG_PROC_FS | ||
| 102 | extern int mpc_proc_init(void); | ||
| 103 | extern void mpc_proc_clean(void); | ||
| 104 | #endif | ||
| 105 | |||
| 106 | struct mpoa_client *mpcs = NULL; /* FIXME */ | 101 | struct mpoa_client *mpcs = NULL; /* FIXME */ |
| 107 | static struct atm_mpoa_qos *qos_head = NULL; | 102 | static struct atm_mpoa_qos *qos_head = NULL; |
| 108 | static DEFINE_TIMER(mpc_timer, NULL, 0, 0); | 103 | static DEFINE_TIMER(mpc_timer, NULL, 0, 0); |
| @@ -1439,12 +1434,8 @@ static __init int atm_mpoa_init(void) · 1330 unmodified lines | |||
| 1439 | { | 1434 | { |
| 1440 | register_atm_ioctl(&atm_ioctl_ops); | 1435 | register_atm_ioctl(&atm_ioctl_ops); |
| 1441 | 1436 | ||
| 1442 | #ifdef CONFIG_PROC_FS | ||
| 1443 | if (mpc_proc_init() != 0) | 1437 | if (mpc_proc_init() != 0) |
| 1444 | printk(KERN_INFO "mpoa: failed to initialize /proc/mpoa\n"); | 1438 | printk(KERN_INFO "mpoa: failed to initialize /proc/mpoa\n"); |
| 1445 | else | ||
| 1446 | printk(KERN_INFO "mpoa: /proc/mpoa initialized\n"); | ||
| 1447 | #endif | ||
| 1448 | 1439 | ||
| 1449 | printk("mpc.c: " __DATE__ " " __TIME__ " initialized\n"); | 1440 | printk("mpc.c: " __DATE__ " " __TIME__ " initialized\n"); |
| 1450 | 1441 | ||
| @@ -1457,9 +1448,7 @@ static void __exit atm_mpoa_cleanup(void) · 6 unmodified lines | |||
| 1457 | struct atm_mpoa_qos *qos, *nextqos; | 1448 | struct atm_mpoa_qos *qos, *nextqos; |
| 1458 | struct lec_priv *priv; | 1449 | struct lec_priv *priv; |
| 1459 | 1450 | ||
| 1460 | #ifdef CONFIG_PROC_FS | ||
| 1461 | mpc_proc_clean(); | 1451 | mpc_proc_clean(); |
| 1462 | #endif | ||
| 1463 | 1452 | ||
| 1464 | del_timer(&mpc_timer); | 1453 | del_timer(&mpc_timer); |
| 1465 | unregister_netdevice_notifier(&mpoa_notifier); | 1454 | unregister_netdevice_notifier(&mpoa_notifier); |
| @@ -50,4 +50,12 @@ int atm_mpoa_delete_qos(struct atm_mpoa_qos *qos); · 49 unmodified lines | |||
| 50 | struct seq_file; | 50 | struct seq_file; |
| 51 | void atm_mpoa_disp_qos(struct seq_file *m); | 51 | void atm_mpoa_disp_qos(struct seq_file *m); |
| 52 | 52 | ||
| 53 | #ifdef CONFIG_PROC_FS | ||
| 54 | int mpc_proc_init(void); | ||
| 55 | void mpc_proc_clean(void); | ||
| 56 | #else | ||
| 57 | #define mpc_proc_init() (0) | ||
| 58 | #define mpc_proc_clean() do { } while(0) | ||
| 59 | #endif | ||
| 60 | |||
| 53 | #endif /* _MPC_H_ */ | 61 | #endif /* _MPC_H_ */ |
| @@ -38,13 +38,10 @@ int br_dev_queue_push_xmit(struct sk_buff *skb) · 37 unmodified lines | |||
| 38 | if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb)) | 38 | if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb)) |
| 39 | kfree_skb(skb); | 39 | kfree_skb(skb); |
| 40 | else { | 40 | else { |
| 41 | #ifdef CONFIG_BRIDGE_NETFILTER | ||
| 42 | /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */ | 41 | /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */ |
| 43 | if (nf_bridge_maybe_copy_header(skb)) | 42 | if (nf_bridge_maybe_copy_header(skb)) |
| 44 | kfree_skb(skb); | 43 | kfree_skb(skb); |
| 45 | else | 44 | else { |
| 46 | #endif | ||
| 47 | { | ||
| 48 | skb_push(skb, ETH_HLEN); | 45 | skb_push(skb, ETH_HLEN); |
| 49 | 46 | ||
| 50 | dev_queue_xmit(skb); | 47 | dev_queue_xmit(skb); |
| @@ -53,10 +53,10 @@ · 52 unmodified lines | |||
| 53 | 53 | ||
| 54 | #ifdef CONFIG_SYSCTL | 54 | #ifdef CONFIG_SYSCTL |
| 55 | static struct ctl_table_header *brnf_sysctl_header; | 55 | static struct ctl_table_header *brnf_sysctl_header; |
| 56 | static int brnf_call_iptables = 1; | 56 | static int brnf_call_iptables __read_mostly = 1; |
| 57 | static int brnf_call_ip6tables = 1; | 57 | static int brnf_call_ip6tables __read_mostly = 1; |
| 58 | static int brnf_call_arptables = 1; | 58 | static int brnf_call_arptables __read_mostly = 1; |
| 59 | static int brnf_filter_vlan_tagged = 1; | 59 | static int brnf_filter_vlan_tagged __read_mostly = 1; |
| 60 | #else | 60 | #else |
| 61 | #define brnf_filter_vlan_tagged 1 | 61 | #define brnf_filter_vlan_tagged 1 |
| 62 | #endif | 62 | #endif |
| @@ -127,14 +127,37 @@ static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) · 64 unmodified lines | |||
| 127 | 127 | ||
| 128 | static inline void nf_bridge_save_header(struct sk_buff *skb) | 128 | static inline void nf_bridge_save_header(struct sk_buff *skb) |
| 129 | { | 129 | { |
| 130 | int header_size = 16; | 130 | int header_size = ETH_HLEN; |
| 131 | 131 | ||
| 132 | if (skb->protocol == htons(ETH_P_8021Q)) | 132 | if (skb->protocol == htons(ETH_P_8021Q)) |
| 133 | header_size = 18; | 133 | header_size += VLAN_HLEN; |
| 134 | 134 | ||
| 135 | memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); | 135 | memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | /* | ||
| 139 | * When forwarding bridge frames, we save a copy of the original | ||
| 140 | * header before processing. | ||
| 141 | */ | ||
| 142 | int nf_bridge_copy_header(struct sk_buff *skb) | ||
| 143 | { | ||
| 144 | int err; | ||
| 145 | int header_size = ETH_HLEN; | ||
| 146 | |||
| 147 | if (skb->protocol == htons(ETH_P_8021Q)) | ||
| 148 | header_size += VLAN_HLEN; | ||
| 149 | |||
| 150 | err = skb_cow(skb, header_size); | ||
| 151 | if (err) | ||
| 152 | return err; | ||
| 153 | |||
| 154 | memcpy(skb->data - header_size, skb->nf_bridge->data, header_size); | ||
| 155 | |||
| 156 | if (skb->protocol == htons(ETH_P_8021Q)) | ||
| 157 | __skb_push(skb, VLAN_HLEN); | ||
| 158 | return 0; | ||
| 159 | } | ||
| 160 | |||
| 138 | /* PF_BRIDGE/PRE_ROUTING *********************************************/ | 161 | /* PF_BRIDGE/PRE_ROUTING *********************************************/ |
| 139 | /* Undo the changes made for ip6tables PREROUTING and continue the | 162 | /* Undo the changes made for ip6tables PREROUTING and continue the |
| 140 | * bridge PRE_ROUTING hook. */ | 163 | * bridge PRE_ROUTING hook. */ |
| @@ -695,16 +718,6 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, · 554 unmodified lines | |||
| 695 | else | 718 | else |
| 696 | pf = PF_INET6; | 719 | pf = PF_INET6; |
| 697 | 720 | ||
| 698 | #ifdef CONFIG_NETFILTER_DEBUG | ||
| 699 | /* Sometimes we get packets with NULL ->dst here (for example, | ||
| 700 | * running a dhcp client daemon triggers this). This should now | ||
| 701 | * be fixed, but let's keep the check around. */ | ||
| 702 | if (skb->dst == NULL) { | ||
| 703 | printk(KERN_CRIT "br_netfilter: skb->dst == NULL."); | ||
| 704 | return NF_ACCEPT; | ||
| 705 | } | ||
| 706 | #endif | ||
| 707 | |||
| 708 | nf_bridge = skb->nf_bridge; | 721 | nf_bridge = skb->nf_bridge; |
| 709 | nf_bridge->physoutdev = skb->dev; | 722 | nf_bridge->physoutdev = skb->dev; |
| 710 | realindev = nf_bridge->physindev; | 723 | realindev = nf_bridge->physindev; |
| @@ -786,7 +799,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, · 75 unmodified lines | |||
| 786 | * keep the check just to be sure... */ | 799 | * keep the check just to be sure... */ |
| 787 | if (skb->mac.raw < skb->head || skb->mac.raw + ETH_HLEN > skb->data) { | 800 | if (skb->mac.raw < skb->head || skb->mac.raw + ETH_HLEN > skb->data) { |
| 788 | printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: " | 801 | printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: " |
| 789 | "bad mac.raw pointer."); | 802 | "bad mac.raw pointer.\n"); |
| 790 | goto print_error; | 803 | goto print_error; |
| 791 | } | 804 | } |
| 792 | #endif | 805 | #endif |
| @@ -804,7 +817,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, · 11 unmodified lines | |||
| 804 | 817 | ||
| 805 | #ifdef CONFIG_NETFILTER_DEBUG | 818 | #ifdef CONFIG_NETFILTER_DEBUG |
| 806 | if (skb->dst == NULL) { | 819 | if (skb->dst == NULL) { |
| 807 | printk(KERN_CRIT "br_netfilter: skb->dst == NULL."); | 820 | printk(KERN_INFO "br_netfilter post_routing: skb->dst == NULL\n"); |
| 808 | goto print_error; | 821 | goto print_error; |
| 809 | } | 822 | } |
| 810 | #endif | 823 | #endif |
| @@ -841,6 +854,7 @@ print_error: · 30 unmodified lines | |||
| 841 | } | 854 | } |
| 842 | printk(" head:%p, raw:%p, data:%p\n", skb->head, skb->mac.raw, | 855 | printk(" head:%p, raw:%p, data:%p\n", skb->head, skb->mac.raw, |
| 843 | skb->data); | 856 | skb->data); |
| 857 | dump_stack(); | ||
| 844 | return NF_ACCEPT; | 858 | return NF_ACCEPT; |
| 845 | #endif | 859 | #endif |
| 846 | } | 860 | } |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/rtnetlink.h> | 14 | #include <linux/rtnetlink.h> |
| 15 | #include <net/netlink.h> | ||
| 15 | #include "br_private.h" | 16 | #include "br_private.h" |
| 16 | 17 | ||
| 17 | /* | 18 | /* |
| @@ -76,26 +77,24 @@ rtattr_failure: · 58 unmodified lines | |||
| 76 | void br_ifinfo_notify(int event, struct net_bridge_port *port) | 77 | void br_ifinfo_notify(int event, struct net_bridge_port *port) |
| 77 | { | 78 | { |
| 78 | struct sk_buff *skb; | 79 | struct sk_buff *skb; |
| 79 | int err = -ENOMEM; | 80 | int payload = sizeof(struct ifinfomsg) + 128; |
| 81 | int err = -ENOBUFS; | ||
| 80 | 82 | ||
| 81 | pr_debug("bridge notify event=%d\n", event); | 83 | pr_debug("bridge notify event=%d\n", event); |
| 82 | skb = alloc_skb(NLMSG_SPACE(sizeof(struct ifinfomsg) + 128), | 84 | skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC); |
| 83 | GFP_ATOMIC); | 85 | if (skb == NULL) |
| 84 | if (!skb) | 86 | goto errout; |
| 85 | goto err_out; | 87 | |
| 88 | err = br_fill_ifinfo(skb, port, 0, 0, event, 0); | ||
| 89 | if (err < 0) { | ||
| 90 | kfree_skb(skb); | ||
| 91 | goto errout; | ||
| 92 | } | ||
| 86 | 93 | ||
| 87 | err = br_fill_ifinfo(skb, port, current->pid, 0, event, 0); | 94 | err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); |
| 95 | errout: | ||
| 88 | if (err < 0) | 96 | if (err < 0) |
| 89 | goto err_kfree; | 97 | rtnl_set_sk_err(RTNLGRP_LINK, err); |
| 90 | |||
| 91 | NETLINK_CB(skb).dst_group = RTNLGRP_LINK; | ||
| 92 | netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_ATOMIC); | ||
| 93 | return; | ||
| 94 | |||
| 95 | err_kfree: | ||
| 96 | kfree_skb(skb); | ||
| 97 | err_out: | ||
| 98 | netlink_set_err(rtnl, 0, RTNLGRP_LINK, err); | ||
| 99 | } | 98 | } |
| 100 | 99 | ||
| 101 | /* | 100 | /* |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | |||
| 24 | #include <linux/vmalloc.h> | 24 | #include <linux/vmalloc.h> |
| 25 | #include <linux/netfilter_bridge/ebtables.h> | 25 | #include <linux/netfilter_bridge/ebtables.h> |
| 26 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
| 27 | #include <linux/mutex.h> | ||
| 27 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
| 28 | #include <linux/smp.h> | 29 | #include <linux/smp.h> |
| 29 | #include <linux/cpumask.h> | 30 | #include <linux/cpumask.h> |
| @@ -31,36 +32,9 @@ · 1 unmodified line | |||
| 31 | /* needed for logical [in,out]-dev filtering */ | 32 | /* needed for logical [in,out]-dev filtering */ |
| 32 | #include "../br_private.h" | 33 | #include "../br_private.h" |
| 33 | 34 | ||
| 34 | /* list_named_find */ | ||
| 35 | #define ASSERT_READ_LOCK(x) | ||
| 36 | #define ASSERT_WRITE_LOCK(x) | ||
| 37 | #include <linux/netfilter_ipv4/listhelp.h> | ||
| 38 | #include <linux/mutex.h> | ||
| 39 | |||
| 40 | #if 0 | ||
| 41 | /* use this for remote debugging | ||
| 42 | * Copyright (C) 1998 by Ori Pomerantz | ||
| 43 | * Print the string to the appropriate tty, the one | ||
| 44 | * the current task uses | ||
| 45 | */ | ||
| 46 | static void print_string(char *str) | ||
| 47 | { | ||
| 48 | struct tty_struct *my_tty; | ||
| 49 | |||
| 50 | /* The tty for the current task */ | ||
| 51 | my_tty = current->signal->tty; | ||
| 52 | if (my_tty != NULL) { | ||
| 53 | my_tty->driver->write(my_tty, 0, str, strlen(str)); | ||
| 54 | my_tty->driver->write(my_tty, 0, "\015\012", 2); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | #define BUGPRINT(args) print_string(args); | ||
| 59 | #else | ||
| 60 | #define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\ | 35 | #define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\ |
| 61 | "report to author: "format, ## args) | 36 | "report to author: "format, ## args) |
| 62 | /* #define BUGPRINT(format, args...) */ | 37 | /* #define BUGPRINT(format, args...) */ |
| 63 | #endif | ||
| 64 | #define MEMPRINT(format, args...) printk("kernel msg: ebtables "\ | 38 | #define MEMPRINT(format, args...) printk("kernel msg: ebtables "\ |
| 65 | ": out of memory: "format, ## args) | 39 | ": out of memory: "format, ## args) |
| 66 | /* #define MEMPRINT(format, args...) */ | 40 | /* #define MEMPRINT(format, args...) */ |
| @@ -299,18 +273,22 @@ static inline void * · 232 unmodified lines | |||
| 299 | find_inlist_lock_noload(struct list_head *head, const char *name, int *error, | 273 | find_inlist_lock_noload(struct list_head *head, const char *name, int *error, |
| 300 | struct mutex *mutex) | 274 | struct mutex *mutex) |
| 301 | { | 275 | { |
| 302 | void *ret; | 276 | struct { |
| 277 | struct list_head list; | ||
| 278 | char name[EBT_FUNCTION_MAXNAMELEN]; | ||
| 279 | } *e; | ||
| 303 | 280 | ||
| 304 | *error = mutex_lock_interruptible(mutex); | 281 | *error = mutex_lock_interruptible(mutex); |
| 305 | if (*error != 0) | 282 | if (*error != 0) |
| 306 | return NULL; | 283 | return NULL; |
| 307 | 284 | ||
| 308 | ret = list_named_find(head, name); | 285 | list_for_each_entry(e, head, list) { |
| 309 | if (!ret) { | 286 | if (strcmp(e->name, name) == 0) |
| 310 | *error = -ENOENT; | 287 | return e; |
| 311 | mutex_unlock(mutex); | ||
| 312 | } | 288 | } |
| 313 | return ret; | 289 | *error = -ENOENT; |
| 290 | mutex_unlock(mutex); | ||
| 291 | return NULL; | ||
| 314 | } | 292 | } |
| 315 | 293 | ||
| 316 | #ifndef CONFIG_KMOD | 294 | #ifndef CONFIG_KMOD |
| @@ -1064,15 +1042,19 @@ free_newinfo: · 747 unmodified lines | |||
| 1064 | 1042 | ||
| 1065 | int ebt_register_target(struct ebt_target *target) | 1043 | int ebt_register_target(struct ebt_target *target) |
| 1066 | { | 1044 | { |
| 1045 | struct ebt_target *t; | ||
| 1067 | int ret; | 1046 | int ret; |
| 1068 | 1047 | ||
| 1069 | ret = mutex_lock_interruptible(&ebt_mutex); | 1048 | ret = mutex_lock_interruptible(&ebt_mutex); |
| 1070 | if (ret != 0) | 1049 | if (ret != 0) |
| 1071 | return ret; | 1050 | return ret; |
| 1072 | if (!list_named_insert(&ebt_targets, target)) { | 1051 | list_for_each_entry(t, &ebt_targets, list) { |
| 1073 | mutex_unlock(&ebt_mutex); | 1052 | if (strcmp(t->name, target->name) == 0) { |
| 1074 | return -EEXIST; | 1053 | mutex_unlock(&ebt_mutex); |
| 1054 | return -EEXIST; | ||
| 1055 | } | ||
| 1075 | } | 1056 | } |
| 1057 | list_add(&target->list, &ebt_targets); | ||
| 1076 | mutex_unlock(&ebt_mutex); | 1058 | mutex_unlock(&ebt_mutex); |
| 1077 | 1059 | ||
| 1078 | return 0; | 1060 | return 0; |
| @@ -1081,21 +1063,25 @@ int ebt_register_target(struct ebt_target *target) · 2 unmodified lines | |||
| 1081 | void ebt_unregister_target(struct ebt_target *target) | 1063 | void ebt_unregister_target(struct ebt_target *target) |
| 1082 | { | 1064 | { |
| 1083 | mutex_lock(&ebt_mutex); | 1065 | mutex_lock(&ebt_mutex); |
| 1084 | LIST_DELETE(&ebt_targets, target); | 1066 | list_del(&target->list); |
| 1085 | mutex_unlock(&ebt_mutex); | 1067 | mutex_unlock(&ebt_mutex); |
| 1086 | } | 1068 | } |
| 1087 | 1069 | ||
| 1088 | int ebt_register_match(struct ebt_match *match) | 1070 | int ebt_register_match(struct ebt_match *match) |
| 1089 | { | 1071 | { |
| 1072 | struct ebt_match *m; | ||
| 1090 | int ret; | 1073 | int ret; |
| 1091 | 1074 | ||
| 1092 | ret = mutex_lock_interruptible(&ebt_mutex); | 1075 | ret = mutex_lock_interruptible(&ebt_mutex); |
| 1093 | if (ret != 0) | 1076 | if (ret != 0) |
| 1094 | return ret; | 1077 | return ret; |
| 1095 | if (!list_named_insert(&ebt_matches, match)) { | 1078 | list_for_each_entry(m, &ebt_matches, list) { |
| 1096 | mutex_unlock(&ebt_mutex); | 1079 | if (strcmp(m->name, match->name) == 0) { |
| 1097 | return -EEXIST; | 1080 | mutex_unlock(&ebt_mutex); |
| 1081 | return -EEXIST; | ||
| 1082 | } | ||
| 1098 | } | 1083 | } |
| 1084 | list_add(&match->list, &ebt_matches); | ||
| 1099 | mutex_unlock(&ebt_mutex); | 1085 | mutex_unlock(&ebt_mutex); |
| 1100 | 1086 | ||
| 1101 | return 0; | 1087 | return 0; |
| @@ -1104,21 +1090,25 @@ int ebt_register_match(struct ebt_match *match) · 2 unmodified lines | |||
| 1104 | void ebt_unregister_match(struct ebt_match *match) | 1090 | void ebt_unregister_match(struct ebt_match *match) |
| 1105 | { | 1091 | { |
| 1106 | mutex_lock(&ebt_mutex); | 1092 | mutex_lock(&ebt_mutex); |
| 1107 | LIST_DELETE(&ebt_matches, match); | 1093 | list_del(&match->list); |
| 1108 | mutex_unlock(&ebt_mutex); | 1094 | mutex_unlock(&ebt_mutex); |
| 1109 | } | 1095 | } |
| 1110 | 1096 | ||
| 1111 | int ebt_register_watcher(struct ebt_watcher *watcher) | 1097 | int ebt_register_watcher(struct ebt_watcher *watcher) |
| 1112 | { | 1098 | { |
| 1099 | struct ebt_watcher *w; | ||
| 1113 | int ret; | 1100 | int ret; |
| 1114 | 1101 | ||
| 1115 | ret = mutex_lock_interruptible(&ebt_mutex); | 1102 | ret = mutex_lock_interruptible(&ebt_mutex); |
| 1116 | if (ret != 0) | 1103 | if (ret != 0) |
| 1117 | return ret; | 1104 | return ret; |
| 1118 | if (!list_named_insert(&ebt_watchers, watcher)) { | 1105 | list_for_each_entry(w, &ebt_watchers, list) { |
| 1119 | mutex_unlock(&ebt_mutex); | 1106 | if (strcmp(w->name, watcher->name) == 0) { |
| 1120 | return -EEXIST; | 1107 | mutex_unlock(&ebt_mutex); |
| 1108 | return -EEXIST; | ||
| 1109 | } | ||
| 1121 | } | 1110 | } |
| 1111 | list_add(&watcher->list, &ebt_watchers); | ||
| 1122 | mutex_unlock(&ebt_mutex); | 1112 | mutex_unlock(&ebt_mutex); |
| 1123 | 1113 | ||
| 1124 | return 0; | 1114 | return 0; |
| @@ -1127,13 +1117,14 @@ int ebt_register_watcher(struct ebt_watcher *watcher) · 2 unmodified lines | |||
| 1127 | void ebt_unregister_watcher(struct ebt_watcher *watcher) | 1117 | void ebt_unregister_watcher(struct ebt_watcher *watcher) |
| 1128 | { | 1118 | { |
| 1129 | mutex_lock(&ebt_mutex); | 1119 | mutex_lock(&ebt_mutex); |
| 1130 | LIST_DELETE(&ebt_watchers, watcher); | 1120 | list_del(&watcher->list); |
| 1131 | mutex_unlock(&ebt_mutex); | 1121 | mutex_unlock(&ebt_mutex); |
| 1132 | } | 1122 | } |
| 1133 | 1123 | ||
| 1134 | int ebt_register_table(struct ebt_table *table) | 1124 | int ebt_register_table(struct ebt_table *table) |
| 1135 | { | 1125 | { |
| 1136 | struct ebt_table_info *newinfo; | 1126 | struct ebt_table_info *newinfo; |
| 1127 | struct ebt_table *t; | ||
| 1137 | int ret, i, countersize; | 1128 | int ret, i, countersize; |
| 1138 | 1129 | ||
| 1139 | if (!table || !table->table ||!table->table->entries || | 1130 | if (!table || !table->table ||!table->table->entries || |
| @@ -1179,10 +1170,12 @@ int ebt_register_table(struct ebt_table *table) · 39 unmodified lines | |||
| 1179 | if (ret != 0) | 1170 | if (ret != 0) |
| 1180 | goto free_chainstack; | 1171 | goto free_chainstack; |
| 1181 | 1172 | ||
| 1182 | if (list_named_find(&ebt_tables, table->name)) { | 1173 | list_for_each_entry(t, &ebt_tables, list) { |
| 1183 | ret = -EEXIST; | 1174 | if (strcmp(t->name, table->name) == 0) { |
| 1184 | BUGPRINT("Table name already exists\n"); | 1175 | ret = -EEXIST; |
| 1185 | goto free_unlock; | 1176 | BUGPRINT("Table name already exists\n"); |
| 1177 | goto free_unlock; | ||
| 1178 | } | ||
| 1186 | } | 1179 | } |
| 1187 | 1180 | ||
| 1188 | /* Hold a reference count if the chains aren't empty */ | 1181 | /* Hold a reference count if the chains aren't empty */ |
| @@ -1190,7 +1183,7 @@ int ebt_register_table(struct ebt_table *table) · 1 unmodified line | |||
| 1190 | ret = -ENOENT; | 1183 | ret = -ENOENT; |
| 1191 | goto free_unlock; | 1184 | goto free_unlock; |
| 1192 | } | 1185 | } |
| 1193 | list_prepend(&ebt_tables, table); | 1186 | list_add(&table->list, &ebt_tables); |
| 1194 | mutex_unlock(&ebt_mutex); | 1187 | mutex_unlock(&ebt_mutex); |
| 1195 | return 0; | 1188 | return 0; |
| 1196 | free_unlock: | 1189 | free_unlock: |
| @@ -1216,7 +1209,7 @@ void ebt_unregister_table(struct ebt_table *table) · 19 unmodified lines | |||
| 1216 | return; | 1209 | return; |
| 1217 | } | 1210 | } |
| 1218 | mutex_lock(&ebt_mutex); | 1211 | mutex_lock(&ebt_mutex); |
| 1219 | LIST_DELETE(&ebt_tables, table); | 1212 | list_del(&table->list); |
| 1220 | mutex_unlock(&ebt_mutex); | 1213 | mutex_unlock(&ebt_mutex); |
| 1221 | vfree(table->private->entries); | 1214 | vfree(table->private->entries); |
| 1222 | if (table->private->chainstack) { | 1215 | if (table->private->chainstack) { |
| @@ -1486,7 +1479,7 @@ static int __init ebtables_init(void) · 263 unmodified lines | |||
| 1486 | int ret; | 1479 | int ret; |
| 1487 | 1480 | ||
| 1488 | mutex_lock(&ebt_mutex); | 1481 | mutex_lock(&ebt_mutex); |
| 1489 | list_named_insert(&ebt_targets, &ebt_standard_target); | 1482 | list_add(&ebt_standard_target.list, &ebt_targets); |
| 1490 | mutex_unlock(&ebt_mutex); | 1483 | mutex_unlock(&ebt_mutex); |
| 1491 | if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0) | 1484 | if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0) |
| 1492 | return ret; | 1485 | return ret; |
| @@ -17,3 +17,4 @@ obj-$(CONFIG_NET_PKTGEN) += pktgen.o · 16 unmodified lines | |||
| 17 | obj-$(CONFIG_WIRELESS_EXT) += wireless.o | 17 | obj-$(CONFIG_WIRELESS_EXT) += wireless.o |
| 18 | obj-$(CONFIG_NETPOLL) += netpoll.o | 18 | obj-$(CONFIG_NETPOLL) += netpoll.o |
| 19 | obj-$(CONFIG_NET_DMA) += user_dma.o | 19 | obj-$(CONFIG_NET_DMA) += user_dma.o |
| 20 | obj-$(CONFIG_FIB_RULES) += fib_rules.o | ||
| @@ -417,7 +417,7 @@ unsigned int __skb_checksum_complete(struct sk_buff *skb) · 416 unmodified lines | |||
| 417 | 417 | ||
| 418 | sum = (u16)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)); | 418 | sum = (u16)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)); |
| 419 | if (likely(!sum)) { | 419 | if (likely(!sum)) { |
| 420 | if (unlikely(skb->ip_summed == CHECKSUM_HW)) | 420 | if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) |
| 421 | netdev_rx_csum_fault(skb->dev); | 421 | netdev_rx_csum_fault(skb->dev); |
| 422 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 422 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 423 | } | 423 | } |
| @@ -462,7 +462,7 @@ int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, · 38 unmodified lines | |||
| 462 | goto fault; | 462 | goto fault; |
| 463 | if ((unsigned short)csum_fold(csum)) | 463 | if ((unsigned short)csum_fold(csum)) |
| 464 | goto csum_error; | 464 | goto csum_error; |
| 465 | if (unlikely(skb->ip_summed == CHECKSUM_HW)) | 465 | if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) |
| 466 | netdev_rx_csum_fault(skb->dev); | 466 | netdev_rx_csum_fault(skb->dev); |
| 467 | iov->iov_len -= chunk; | 467 | iov->iov_len -= chunk; |
| 468 | iov->iov_base += chunk; | 468 | iov->iov_base += chunk; |
| @@ -640,6 +640,8 @@ int dev_valid_name(const char *name) · 639 unmodified lines | |||
| 640 | { | 640 | { |
| 641 | if (*name == '\0') | 641 | if (*name == '\0') |
| 642 | return 0; | 642 | return 0; |
| 643 | if (strlen(name) >= IFNAMSIZ) | ||
| 644 | return 0; | ||
| 643 | if (!strcmp(name, ".") || !strcmp(name, "..")) | 645 | if (!strcmp(name, ".") || !strcmp(name, "..")) |
| 644 | return 0; | 646 | return 0; |
| 645 | 647 | ||
| @@ -1166,12 +1168,12 @@ EXPORT_SYMBOL(netif_device_attach); · 520 unmodified lines | |||
| 1166 | * Invalidate hardware checksum when packet is to be mangled, and | 1168 | * Invalidate hardware checksum when packet is to be mangled, and |
| 1167 | * complete checksum manually on outgoing path. | 1169 | * complete checksum manually on outgoing path. |
| 1168 | */ | 1170 | */ |
| 1169 | int skb_checksum_help(struct sk_buff *skb, int inward) | 1171 | int skb_checksum_help(struct sk_buff *skb) |
| 1170 | { | 1172 | { |
| 1171 | unsigned int csum; | 1173 | unsigned int csum; |
| 1172 | int ret = 0, offset = skb->h.raw - skb->data; | 1174 | int ret = 0, offset = skb->h.raw - skb->data; |
| 1173 | 1175 | ||
| 1174 | if (inward) | 1176 | if (skb->ip_summed == CHECKSUM_COMPLETE) |
| 1175 | goto out_set_summed; | 1177 | goto out_set_summed; |
| 1176 | 1178 | ||
| 1177 | if (unlikely(skb_shinfo(skb)->gso_size)) { | 1179 | if (unlikely(skb_shinfo(skb)->gso_size)) { |
| @@ -1223,7 +1225,7 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) · 45 unmodified lines | |||
| 1223 | skb->mac_len = skb->nh.raw - skb->data; | 1225 | skb->mac_len = skb->nh.raw - skb->data; |
| 1224 | __skb_pull(skb, skb->mac_len); | 1226 | __skb_pull(skb, skb->mac_len); |
| 1225 | 1227 | ||
| 1226 | if (unlikely(skb->ip_summed != CHECKSUM_HW)) { | 1228 | if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { |
| 1227 | if (skb_header_cloned(skb) && | 1229 | if (skb_header_cloned(skb) && |
| 1228 | (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) | 1230 | (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) |
| 1229 | return ERR_PTR(err); | 1231 | return ERR_PTR(err); |
| @@ -1232,7 +1234,7 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) · 2 unmodified lines | |||
| 1232 | rcu_read_lock(); | 1234 | rcu_read_lock(); |
| 1233 | list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) { | 1235 | list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) { |
| 1234 | if (ptype->type == type && !ptype->dev && ptype->gso_segment) { | 1236 | if (ptype->type == type && !ptype->dev && ptype->gso_segment) { |
| 1235 | if (unlikely(skb->ip_summed != CHECKSUM_HW)) { | 1237 | if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { |
| 1236 | err = ptype->gso_send_check(skb); | 1238 | err = ptype->gso_send_check(skb); |
| 1237 | segs = ERR_PTR(err); | 1239 | segs = ERR_PTR(err); |
| 1238 | if (err || skb_gso_ok(skb, features)) | 1240 | if (err || skb_gso_ok(skb, features)) |
| @@ -1444,11 +1446,11 @@ int dev_queue_xmit(struct sk_buff *skb) · 205 unmodified lines | |||
| 1444 | /* If packet is not checksummed and device does not support | 1446 | /* If packet is not checksummed and device does not support |
| 1445 | * checksumming for this protocol, complete checksumming here. | 1447 | * checksumming for this protocol, complete checksumming here. |
| 1446 | */ | 1448 | */ |
| 1447 | if (skb->ip_summed == CHECKSUM_HW && | 1449 | if (skb->ip_summed == CHECKSUM_PARTIAL && |
| 1448 | (!(dev->features & NETIF_F_GEN_CSUM) && | 1450 | (!(dev->features & NETIF_F_GEN_CSUM) && |
| 1449 | (!(dev->features & NETIF_F_IP_CSUM) || | 1451 | (!(dev->features & NETIF_F_IP_CSUM) || |
| 1450 | skb->protocol != htons(ETH_P_IP)))) | 1452 | skb->protocol != htons(ETH_P_IP)))) |
| 1451 | if (skb_checksum_help(skb, 0)) | 1453 | if (skb_checksum_help(skb)) |
| 1452 | goto out_kfree_skb; | 1454 | goto out_kfree_skb; |
| 1453 | 1455 | ||
| 1454 | gso: | 1456 | gso: |
| @@ -3191,13 +3193,15 @@ struct net_device *alloc_netdev(int sizeof_priv, const char *name, · 1736 unmodified lines | |||
| 3191 | struct net_device *dev; | 3193 | struct net_device *dev; |
| 3192 | int alloc_size; | 3194 | int alloc_size; |
| 3193 | 3195 | ||
| 3196 | BUG_ON(strlen(name) >= sizeof(dev->name)); | ||
| 3197 | |||
| 3194 | /* ensure 32-byte alignment of both the device and private area */ | 3198 | /* ensure 32-byte alignment of both the device and private area */ |
| 3195 | alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST; | 3199 | alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST; |
| 3196 | alloc_size += sizeof_priv + NETDEV_ALIGN_CONST; | 3200 | alloc_size += sizeof_priv + NETDEV_ALIGN_CONST; |
| 3197 | 3201 | ||
| 3198 | p = kzalloc(alloc_size, GFP_KERNEL); | 3202 | p = kzalloc(alloc_size, GFP_KERNEL); |
| 3199 | if (!p) { | 3203 | if (!p) { |
| 3200 | printk(KERN_ERR "alloc_dev: Unable to allocate device.\n"); | 3204 | printk(KERN_ERR "alloc_netdev: Unable to allocate device.\n"); |
| 3201 | return NULL; | 3205 | return NULL; |
| 3202 | } | 3206 | } |
| 3203 | 3207 | ||
| @@ -21,8 +21,7 @@ · 20 unmodified lines | |||
| 21 | * 2 of the License, or (at your option) any later version. | 21 | * 2 of the License, or (at your option) any later version. |
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | #include <linux/config.h> | 24 | #include <linux/module.h> |
| 25 | #include <linux/module.h> | ||
| 26 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
| 27 | #include <asm/system.h> | 26 | #include <asm/system.h> |
| 28 | #include <linux/bitops.h> | 27 | #include <linux/bitops.h> |
| @@ -0,0 +1,421 @@ | |||
| 1 | /* | ||
| 2 | * net/core/fib_rules.c Generic Routing Rules | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License as | ||
| 6 | * published by the Free Software Foundation, version 2. | ||
| 7 | * | ||
| 8 | * Authors: Thomas Graf <tgraf@suug.ch> | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/config.h> | ||
| 12 | #include <linux/types.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/list.h> | ||
| 15 | #include <net/fib_rules.h> | ||
| 16 | |||
| 17 | static LIST_HEAD(rules_ops); | ||
| 18 | static DEFINE_SPINLOCK(rules_mod_lock); | ||
| 19 | |||
| 20 | static void notify_rule_change(int event, struct fib_rule *rule, | ||
| 21 | struct fib_rules_ops *ops, struct nlmsghdr *nlh, | ||
| 22 | u32 pid); | ||
| 23 | |||
| 24 | static struct fib_rules_ops *lookup_rules_ops(int family) | ||
| 25 | { | ||
| 26 | struct fib_rules_ops *ops; | ||
| 27 | |||
| 28 | rcu_read_lock(); | ||
| 29 | list_for_each_entry_rcu(ops, &rules_ops, list) { | ||
| 30 | if (ops->family == family) { | ||
| 31 | if (!try_module_get(ops->owner)) | ||
| 32 | ops = NULL; | ||
| 33 | rcu_read_unlock(); | ||
| 34 | return ops; | ||
| 35 | } | ||
| 36 | } | ||
| 37 | rcu_read_unlock(); | ||
| 38 | |||
| 39 | return NULL; | ||
| 40 | } | ||
| 41 | |||
| 42 | static void rules_ops_put(struct fib_rules_ops *ops) | ||
| 43 | { | ||
| 44 | if (ops) | ||
| 45 | module_put(ops->owner); | ||
| 46 | } | ||
| 47 | |||
| 48 | int fib_rules_register(struct fib_rules_ops *ops) | ||
| 49 | { | ||
| 50 | int err = -EEXIST; | ||
| 51 | struct fib_rules_ops *o; | ||
| 52 | |||
| 53 | if (ops->rule_size < sizeof(struct fib_rule)) | ||
| 54 | return -EINVAL; | ||
| 55 | |||
| 56 | if (ops->match == NULL || ops->configure == NULL || | ||
| 57 | ops->compare == NULL || ops->fill == NULL || | ||
| 58 | ops->action == NULL) | ||
| 59 | return -EINVAL; | ||
| 60 | |||
| 61 | spin_lock(&rules_mod_lock); | ||
| 62 | list_for_each_entry(o, &rules_ops, list) | ||
| 63 | if (ops->family == o->family) | ||
| 64 | goto errout; | ||
| 65 | |||
| 66 | list_add_tail_rcu(&ops->list, &rules_ops); | ||
| 67 | err = 0; | ||
| 68 | errout: | ||
| 69 | spin_unlock(&rules_mod_lock); | ||
| 70 | |||
| 71 | return err; | ||
| 72 | } | ||
| 73 | |||
| 74 | EXPORT_SYMBOL_GPL(fib_rules_register); | ||
| 75 | |||
| 76 | static void cleanup_ops(struct fib_rules_ops *ops) | ||
| 77 | { | ||
| 78 | struct fib_rule *rule, *tmp; | ||
| 79 | |||
| 80 | list_for_each_entry_safe(rule, tmp, ops->rules_list, list) { | ||
| 81 | list_del_rcu(&rule->list); | ||
| 82 | fib_rule_put(rule); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | int fib_rules_unregister(struct fib_rules_ops *ops) | ||
| 87 | { | ||
| 88 | int err = 0; | ||
| 89 | struct fib_rules_ops *o; | ||
| 90 | |||
| 91 | spin_lock(&rules_mod_lock); | ||
| 92 | list_for_each_entry(o, &rules_ops, list) { | ||
| 93 | if (o == ops) { | ||
| 94 | list_del_rcu(&o->list); | ||
| 95 | cleanup_ops(ops); | ||
| 96 | goto out; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | err = -ENOENT; | ||
| 101 | out: | ||
| 102 | spin_unlock(&rules_mod_lock); | ||
| 103 | |||
| 104 | synchronize_rcu(); | ||
| 105 | |||
| 106 | return err; | ||
| 107 | } | ||
| 108 | |||
| 109 | EXPORT_SYMBOL_GPL(fib_rules_unregister); | ||
| 110 | |||
| 111 | int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl, | ||
| 112 | int flags, struct fib_lookup_arg *arg) | ||
| 113 | { | ||
| 114 | struct fib_rule *rule; | ||
| 115 | int err; | ||
| 116 | |||
| 117 | rcu_read_lock(); | ||
| 118 | |||
| 119 | list_for_each_entry_rcu(rule, ops->rules_list, list) { | ||
| 120 | if (rule->ifindex && (rule->ifindex != fl->iif)) | ||
| 121 | continue; | ||
| 122 | |||
| 123 | if (!ops->match(rule, fl, flags)) | ||
| 124 | continue; | ||
| 125 | |||
| 126 | err = ops->action(rule, fl, flags, arg); | ||
| 127 | if (err != -EAGAIN) { | ||
| 128 | fib_rule_get(rule); | ||
| 129 | arg->rule = rule; | ||
| 130 | goto out; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | err = -ENETUNREACH; | ||
| 135 | out: | ||
| 136 | rcu_read_unlock(); | ||
| 137 | |||
| 138 | return err; | ||
| 139 | } | ||
| 140 | |||
| 141 | EXPORT_SYMBOL_GPL(fib_rules_lookup); | ||
| 142 | |||
| 143 | int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | ||
| 144 | { | ||
| 145 | struct fib_rule_hdr *frh = nlmsg_data(nlh); | ||
| 146 | struct fib_rules_ops *ops = NULL; | ||
| 147 | struct fib_rule *rule, *r, *last = NULL; | ||
| 148 | struct nlattr *tb[FRA_MAX+1]; | ||
| 149 | int err = -EINVAL; | ||
| 150 | |||
| 151 | if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh))) | ||
| 152 | goto errout; | ||
| 153 | |||
| 154 | ops = lookup_rules_ops(frh->family); | ||
| 155 | if (ops == NULL) { | ||
| 156 | err = EAFNOSUPPORT; | ||
| 157 | goto errout; | ||
| 158 | } | ||
| 159 | |||
| 160 | err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy); | ||
| 161 | if (err < 0) | ||
| 162 | goto errout; | ||
| 163 | |||
| 164 | rule = kzalloc(ops->rule_size, GFP_KERNEL); | ||
| 165 | if (rule == NULL) { | ||
| 166 | err = -ENOMEM; | ||
| 167 | goto errout; | ||
| 168 | } | ||
| 169 | |||
| 170 | if (tb[FRA_PRIORITY]) | ||
| 171 | rule->pref = nla_get_u32(tb[FRA_PRIORITY]); | ||
| 172 | |||
| 173 | if (tb[FRA_IFNAME]) { | ||
| 174 | struct net_device *dev; | ||
| 175 | |||
| 176 | rule->ifindex = -1; | ||
| 177 | nla_strlcpy(rule->ifname, tb[FRA_IFNAME], IFNAMSIZ); | ||
| 178 | dev = __dev_get_by_name(rule->ifname); | ||
| 179 | if (dev) | ||
| 180 | rule->ifindex = dev->ifindex; | ||
| 181 | } | ||
| 182 | |||
| 183 | rule->action = frh->action; | ||
| 184 | rule->flags = frh->flags; | ||
| 185 | rule->table = frh_get_table(frh, tb); | ||
| 186 | |||
| 187 | if (!rule->pref && ops->default_pref) | ||
| 188 | rule->pref = ops->default_pref(); | ||
| 189 | |||
| 190 | err = ops->configure(rule, skb, nlh, frh, tb); | ||
| 191 | if (err < 0) | ||
| 192 | goto errout_free; | ||
| 193 | |||
| 194 | list_for_each_entry(r, ops->rules_list, list) { | ||
| 195 | if (r->pref > rule->pref) | ||
| 196 | break; | ||
| 197 | last = r; | ||
| 198 | } | ||
| 199 | |||
| 200 | fib_rule_get(rule); | ||
| 201 | |||
| 202 | if (last) | ||
| 203 | list_add_rcu(&rule->list, &last->list); | ||
| 204 | else | ||
| 205 | list_add_rcu(&rule->list, ops->rules_list); | ||
| 206 | |||
| 207 | notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).pid); | ||
| 208 | rules_ops_put(ops); | ||
| 209 | return 0; | ||
| 210 | |||
| 211 | errout_free: | ||
| 212 | kfree(rule); | ||
| 213 | errout: | ||
| 214 | rules_ops_put(ops); | ||
| 215 | return err; | ||
| 216 | } | ||
| 217 | |||
| 218 | int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | ||
| 219 | { | ||
| 220 | struct fib_rule_hdr *frh = nlmsg_data(nlh); | ||
| 221 | struct fib_rules_ops *ops = NULL; | ||
| 222 | struct fib_rule *rule; | ||
| 223 | struct nlattr *tb[FRA_MAX+1]; | ||
| 224 | int err = -EINVAL; | ||
| 225 | |||
| 226 | if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh))) | ||
| 227 | goto errout; | ||
| 228 | |||
| 229 | ops = lookup_rules_ops(frh->family); | ||
| 230 | if (ops == NULL) { | ||
| 231 | err = EAFNOSUPPORT; | ||
| 232 | goto errout; | ||
| 233 | } | ||
| 234 | |||
| 235 | err = nlmsg_parse(nlh, sizeof(*frh), tb, FRA_MAX, ops->policy); | ||
| 236 | if (err < 0) | ||
| 237 | goto errout; | ||
| 238 | |||
| 239 | list_for_each_entry(rule, ops->rules_list, list) { | ||
| 240 | if (frh->action && (frh->action != rule->action)) | ||
| 241 | continue; | ||
| 242 | |||
| 243 | if (frh->table && (frh_get_table(frh, tb) != rule->table)) | ||
| 244 | continue; | ||
| 245 | |||
| 246 | if (tb[FRA_PRIORITY] && | ||
| 247 | (rule->pref != nla_get_u32(tb[FRA_PRIORITY]))) | ||
| 248 | continue; | ||
| 249 | |||
| 250 | if (tb[FRA_IFNAME] && | ||
| 251 | nla_strcmp(tb[FRA_IFNAME], rule->ifname)) | ||
| 252 | continue; | ||
| 253 | |||
| 254 | if (!ops->compare(rule, frh, tb)) | ||
| 255 | continue; | ||
| 256 | |||
| 257 | if (rule->flags & FIB_RULE_PERMANENT) { | ||
| 258 | err = -EPERM; | ||
| 259 | goto errout; | ||
| 260 | } | ||
| 261 | |||
| 262 | list_del_rcu(&rule->list); | ||
| 263 | synchronize_rcu(); | ||
| 264 | notify_rule_change(RTM_DELRULE, rule, ops, nlh, | ||
| 265 | NETLINK_CB(skb).pid); | ||
| 266 | fib_rule_put(rule); | ||
| 267 | rules_ops_put(ops); | ||
| 268 | return 0; | ||
| 269 | } | ||
| 270 | |||
| 271 | err = -ENOENT; | ||
| 272 | errout: | ||
| 273 | rules_ops_put(ops); | ||
| 274 | return err; | ||
| 275 | } | ||
| 276 | |||
| 277 | static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, | ||
| 278 | u32 pid, u32 seq, int type, int flags, | ||
| 279 | struct fib_rules_ops *ops) | ||
| 280 | { | ||
| 281 | struct nlmsghdr *nlh; | ||
| 282 | struct fib_rule_hdr *frh; | ||
| 283 | |||
| 284 | nlh = nlmsg_put(skb, pid, seq, type, sizeof(*frh), flags); | ||
| 285 | if (nlh == NULL) | ||
| 286 | return -1; | ||
| 287 | |||
| 288 | frh = nlmsg_data(nlh); | ||
| 289 | frh->table = rule->table; | ||
| 290 | NLA_PUT_U32(skb, FRA_TABLE, rule->table); | ||
| 291 | frh->res1 = 0; | ||
| 292 | frh->res2 = 0; | ||
| 293 | frh->action = rule->action; | ||
| 294 | frh->flags = rule->flags; | ||
| 295 | |||
| 296 | if (rule->ifname[0]) | ||
| 297 | NLA_PUT_STRING(skb, FRA_IFNAME, rule->ifname); | ||
| 298 | |||
| 299 | if (rule->pref) | ||
| 300 | NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref); | ||
| 301 | |||
| 302 | if (ops->fill(rule, skb, nlh, frh) < 0) | ||
| 303 | goto nla_put_failure; | ||
| 304 | |||
| 305 | return nlmsg_end(skb, nlh); | ||
| 306 | |||
| 307 | nla_put_failure: | ||
| 308 | return nlmsg_cancel(skb, nlh); | ||
| 309 | } | ||
| 310 | |||
| 311 | int fib_rules_dump(struct sk_buff *skb, struct netlink_callback *cb, int family) | ||
| 312 | { | ||
| 313 | int idx = 0; | ||
| 314 | struct fib_rule *rule; | ||
| 315 | struct fib_rules_ops *ops; | ||
| 316 | |||
| 317 | ops = lookup_rules_ops(family); | ||
| 318 | if (ops == NULL) | ||
| 319 | return -EAFNOSUPPORT; | ||
| 320 | |||
| 321 | rcu_read_lock(); | ||
| 322 | list_for_each_entry(rule, ops->rules_list, list) { | ||
| 323 | if (idx < cb->args[0]) | ||
| 324 | goto skip; | ||
| 325 | |||
| 326 | if (fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).pid, | ||
| 327 | cb->nlh->nlmsg_seq, RTM_NEWRULE, | ||
| 328 | NLM_F_MULTI, ops) < 0) | ||
| 329 | break; | ||
| 330 | skip: | ||
| 331 | idx++; | ||
| 332 | } | ||
| 333 | rcu_read_unlock(); | ||
| 334 | cb->args[0] = idx; | ||
| 335 | rules_ops_put(ops); | ||
| 336 | |||
| 337 | return skb->len; | ||
| 338 | } | ||
| 339 | |||
| 340 | EXPORT_SYMBOL_GPL(fib_rules_dump); | ||
| 341 | |||
| 342 | static void notify_rule_change(int event, struct fib_rule *rule, | ||
| 343 | struct fib_rules_ops *ops, struct nlmsghdr *nlh, | ||
| 344 | u32 pid) | ||
| 345 | { | ||
| 346 | struct sk_buff *skb; | ||
| 347 | int err = -ENOBUFS; | ||
| 348 | |||
| 349 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | ||
| 350 | if (skb == NULL) | ||
| 351 | goto errout; | ||
| 352 | |||
| 353 | err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); | ||
| 354 | if (err < 0) { | ||
| 355 | kfree_skb(skb); | ||
| 356 | goto errout; | ||
| 357 | } | ||
| 358 | |||
| 359 | err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL); | ||
| 360 | errout: | ||
| 361 | if (err < 0) | ||
| 362 | rtnl_set_sk_err(ops->nlgroup, err); | ||
| 363 | } | ||
| 364 | |||
| 365 | static void attach_rules(struct list_head *rules, struct net_device *dev) | ||
| 366 | { | ||
| 367 | struct fib_rule *rule; | ||
| 368 | |||
| 369 | list_for_each_entry(rule, rules, list) { | ||
| 370 | if (rule->ifindex == -1 && | ||
| 371 | strcmp(dev->name, rule->ifname) == 0) | ||
| 372 | rule->ifindex = dev->ifindex; | ||
| 373 | } | ||
| 374 | } | ||
| 375 | |||
| 376 | static void detach_rules(struct list_head *rules, struct net_device *dev) | ||
| 377 | { | ||
| 378 | struct fib_rule *rule; | ||
| 379 | |||
| 380 | list_for_each_entry(rule, rules, list) | ||
| 381 | if (rule->ifindex == dev->ifindex) | ||
| 382 | rule->ifindex = -1; | ||
| 383 | } | ||
| 384 | |||
| 385 | |||
| 386 | static int fib_rules_event(struct notifier_block *this, unsigned long event, | ||
| 387 | void *ptr) | ||
| 388 | { | ||
| 389 | struct net_device *dev = ptr; | ||
| 390 | struct fib_rules_ops *ops; | ||
| 391 | |||
| 392 | ASSERT_RTNL(); | ||
| 393 | rcu_read_lock(); | ||
| 394 | |||
| 395 | switch (event) { | ||
| 396 | case NETDEV_REGISTER: | ||
| 397 | list_for_each_entry(ops, &rules_ops, list) | ||
| 398 | attach_rules(ops->rules_list, dev); | ||
| 399 | break; | ||
| 400 | |||
| 401 | case NETDEV_UNREGISTER: | ||
| 402 | list_for_each_entry(ops, &rules_ops, list) | ||
| 403 | detach_rules(ops->rules_list, dev); | ||
| 404 | break; | ||
| 405 | } | ||
| 406 | |||
| 407 | rcu_read_unlock(); | ||
| 408 | |||
| 409 | return NOTIFY_DONE; | ||
| 410 | } | ||
| 411 | |||
| 412 | static struct notifier_block fib_rules_notifier = { | ||
| 413 | .notifier_call = fib_rules_event, | ||
| 414 | }; | ||
| 415 | |||
| 416 | static int __init fib_rules_init(void) | ||
| 417 | { | ||
| 418 | return register_netdevice_notifier(&fib_rules_notifier); | ||
| 419 | } | ||
| 420 | |||
| 421 | subsys_initcall(fib_rules_init); | ||
| @@ -422,10 +422,10 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) · 421 unmodified lines | |||
| 422 | if (!err) { | 422 | if (!err) { |
| 423 | struct sk_filter *old_fp; | 423 | struct sk_filter *old_fp; |
| 424 | 424 | ||
| 425 | spin_lock_bh(&sk->sk_lock.slock); | 425 | rcu_read_lock_bh(); |
| 426 | old_fp = sk->sk_filter; | 426 | old_fp = rcu_dereference(sk->sk_filter); |
| 427 | sk->sk_filter = fp; | 427 | rcu_assign_pointer(sk->sk_filter, fp); |
| 428 | spin_unlock_bh(&sk->sk_lock.slock); | 428 | rcu_read_unlock_bh(); |
| 429 | fp = old_fp; | 429 | fp = old_fp; |
| 430 | } | 430 | } |
| 431 | 431 | ||
| @@ -32,7 +32,6 @@ struct flow_cache_entry { · 31 unmodified lines | |||
| 32 | u8 dir; | 32 | u8 dir; |
| 33 | struct flowi key; | 33 | struct flowi key; |
| 34 | u32 genid; | 34 | u32 genid; |
| 35 | u32 sk_sid; | ||
| 36 | void *object; | 35 | void *object; |
| 37 | atomic_t *object_ref; | 36 | atomic_t *object_ref; |
| 38 | }; | 37 | }; |
| @@ -165,7 +164,7 @@ static int flow_key_compare(struct flowi *key1, struct flowi *key2) · 126 unmodified lines | |||
| 165 | return 0; | 164 | return 0; |
| 166 | } | 165 | } |
| 167 | 166 | ||
| 168 | void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir, | 167 | void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, |
| 169 | flow_resolve_t resolver) | 168 | flow_resolve_t resolver) |
| 170 | { | 169 | { |
| 171 | struct flow_cache_entry *fle, **head; | 170 | struct flow_cache_entry *fle, **head; |
| @@ -189,7 +188,6 @@ void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir, · 17 unmodified lines | |||
| 189 | for (fle = *head; fle; fle = fle->next) { | 188 | for (fle = *head; fle; fle = fle->next) { |
| 190 | if (fle->family == family && | 189 | if (fle->family == family && |
| 191 | fle->dir == dir && | 190 | fle->dir == dir && |
| 192 | fle->sk_sid == sk_sid && | ||
| 193 | flow_key_compare(key, &fle->key) == 0) { | 191 | flow_key_compare(key, &fle->key) == 0) { |
| 194 | if (fle->genid == atomic_read(&flow_cache_genid)) { | 192 | if (fle->genid == atomic_read(&flow_cache_genid)) { |
| 195 | void *ret = fle->object; | 193 | void *ret = fle->object; |
| @@ -214,7 +212,6 @@ void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir, · 18 unmodified lines | |||
| 214 | *head = fle; | 212 | *head = fle; |
| 215 | fle->family = family; | 213 | fle->family = family; |
| 216 | fle->dir = dir; | 214 | fle->dir = dir; |
| 217 | fle->sk_sid = sk_sid; | ||
| 218 | memcpy(&fle->key, key, sizeof(*key)); | 215 | memcpy(&fle->key, key, sizeof(*key)); |
| 219 | fle->object = NULL; | 216 | fle->object = NULL; |
| 220 | flow_count(cpu)++; | 217 | flow_count(cpu)++; |
| @@ -226,7 +223,7 @@ nocache: · 5 unmodified lines | |||
| 226 | void *obj; | 223 | void *obj; |
| 227 | atomic_t *obj_ref; | 224 | atomic_t *obj_ref; |
| 228 | 225 | ||
| 229 | resolver(key, sk_sid, family, dir, &obj, &obj_ref); | 226 | resolver(key, family, dir, &obj, &obj_ref); |
| 230 | 227 | ||
| 231 | if (fle) { | 228 | if (fle) { |
| 232 | fle->genid = atomic_read(&flow_cache_genid); | 229 | fle->genid = atomic_read(&flow_cache_genid); |
| @@ -346,12 +343,8 @@ static int __init flow_cache_init(void) · 113 unmodified lines | |||
| 346 | 343 | ||
| 347 | flow_cachep = kmem_cache_create("flow_cache", | 344 | flow_cachep = kmem_cache_create("flow_cache", |
| 348 | sizeof(struct flow_cache_entry), | 345 | sizeof(struct flow_cache_entry), |
| 349 | 0, SLAB_HWCACHE_ALIGN, | 346 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, |
| 350 | NULL, NULL); | 347 | NULL, NULL); |
| 351 | |||
| 352 | if (!flow_cachep) | ||
| 353 | panic("NET: failed to allocate flow cache slab\n"); | ||
| 354 | |||
| 355 | flow_hash_shift = 10; | 348 | flow_hash_shift = 10; |
| 356 | flow_lwm = 2 * flow_hash_size; | 349 | flow_lwm = 2 * flow_hash_size; |
| 357 | flow_hwm = 4 * flow_hash_size; | 350 | flow_hwm = 4 * flow_hash_size; |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | |||
| 30 | #include <net/dst.h> | 30 | #include <net/dst.h> |
| 31 | #include <net/sock.h> | 31 | #include <net/sock.h> |
| 32 | #include <net/netevent.h> | 32 | #include <net/netevent.h> |
| 33 | #include <net/netlink.h> | ||
| 33 | #include <linux/rtnetlink.h> | 34 | #include <linux/rtnetlink.h> |
| 34 | #include <linux/random.h> | 35 | #include <linux/random.h> |
| 35 | #include <linux/string.h> | 36 | #include <linux/string.h> |
| @@ -888,7 +889,7 @@ out_unlock_bh: · 852 unmodified lines | |||
| 888 | return rc; | 889 | return rc; |
| 889 | } | 890 | } |
| 890 | 891 | ||
| 891 | static __inline__ void neigh_update_hhs(struct neighbour *neigh) | 892 | static void neigh_update_hhs(struct neighbour *neigh) |
| 892 | { | 893 | { |
| 893 | struct hh_cache *hh; | 894 | struct hh_cache *hh; |
| 894 | void (*update)(struct hh_cache*, struct net_device*, unsigned char *) = | 895 | void (*update)(struct hh_cache*, struct net_device*, unsigned char *) = |
| @@ -1338,14 +1339,10 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl) · 443 unmodified lines | |||
| 1338 | neigh_rand_reach_time(tbl->parms.base_reachable_time); | 1339 | neigh_rand_reach_time(tbl->parms.base_reachable_time); |
| 1339 | 1340 | ||
| 1340 | if (!tbl->kmem_cachep) | 1341 | if (!tbl->kmem_cachep) |
| 1341 | tbl->kmem_cachep = kmem_cache_create(tbl->id, | 1342 | tbl->kmem_cachep = |
| 1342 | tbl->entry_size, | 1343 | kmem_cache_create(tbl->id, tbl->entry_size, 0, |
| 1343 | 0, SLAB_HWCACHE_ALIGN, | 1344 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, |
| 1344 | NULL, NULL); | 1345 | NULL, NULL); |
| 1345 | |||
| 1346 | if (!tbl->kmem_cachep) | ||
| 1347 | panic("cannot create neighbour cache"); | ||
| 1348 | |||
| 1349 | tbl->stats = alloc_percpu(struct neigh_statistics); | 1346 | tbl->stats = alloc_percpu(struct neigh_statistics); |
| 1350 | if (!tbl->stats) | 1347 | if (!tbl->stats) |
| 1351 | panic("cannot create neighbour cache statistics"); | 1348 | panic("cannot create neighbour cache statistics"); |
| @@ -1440,48 +1437,62 @@ int neigh_table_clear(struct neigh_table *tbl) · 88 unmodified lines | |||
| 1440 | 1437 | ||
| 1441 | int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1438 | int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
| 1442 | { | 1439 | { |
| 1443 | struct ndmsg *ndm = NLMSG_DATA(nlh); | 1440 | struct ndmsg *ndm; |
| 1444 | struct rtattr **nda = arg; | 1441 | struct nlattr *dst_attr; |
| 1445 | struct neigh_table *tbl; | 1442 | struct neigh_table *tbl; |
| 1446 | struct net_device *dev = NULL; | 1443 | struct net_device *dev = NULL; |
| 1447 | int err = -ENODEV; | 1444 | int err = -EINVAL; |
| 1448 | 1445 | ||
| 1449 | if (ndm->ndm_ifindex && | 1446 | if (nlmsg_len(nlh) < sizeof(*ndm)) |
| 1450 | (dev = dev_get_by_index(ndm->ndm_ifindex)) == NULL) | ||
| 1451 | goto out; | 1447 | goto out; |
| 1452 | 1448 | ||
| 1449 | dst_attr = nlmsg_find_attr(nlh, sizeof(*ndm), NDA_DST); | ||
| 1450 | if (dst_attr == NULL) | ||
| 1451 | goto out; | ||
| 1452 | |||
| 1453 | ndm = nlmsg_data(nlh); | ||
| 1454 | if (ndm->ndm_ifindex) { | ||
| 1455 | dev = dev_get_by_index(ndm->ndm_ifindex); | ||
| 1456 | if (dev == NULL) { | ||
| 1457 | err = -ENODEV; | ||
| 1458 | goto out; | ||
| 1459 | } | ||
| 1460 | } | ||
| 1461 | |||
| 1453 | read_lock(&neigh_tbl_lock); | 1462 | read_lock(&neigh_tbl_lock); |
| 1454 | for (tbl = neigh_tables; tbl; tbl = tbl->next) { | 1463 | for (tbl = neigh_tables; tbl; tbl = tbl->next) { |
| 1455 | struct rtattr *dst_attr = nda[NDA_DST - 1]; | 1464 | struct neighbour *neigh; |
| 1456 | struct neighbour *n; | ||
| 1457 | 1465 | ||
| 1458 | if (tbl->family != ndm->ndm_family) | 1466 | if (tbl->family != ndm->ndm_family) |
| 1459 | continue; | 1467 | continue; |
| 1460 | read_unlock(&neigh_tbl_lock); | 1468 | read_unlock(&neigh_tbl_lock); |
| 1461 | 1469 | ||
| 1462 | err = -EINVAL; | 1470 | if (nla_len(dst_attr) < tbl->key_len) |
| 1463 | if (!dst_attr || RTA_PAYLOAD(dst_attr) < tbl->key_len) | ||
| 1464 | goto out_dev_put; | 1471 | goto out_dev_put; |
| 1465 | 1472 | ||
| 1466 | if (ndm->ndm_flags & NTF_PROXY) { | 1473 | if (ndm->ndm_flags & NTF_PROXY) { |
| 1467 | err = pneigh_delete(tbl, RTA_DATA(dst_attr), dev); | 1474 | err = pneigh_delete(tbl, nla_data(dst_attr), dev); |
| 1468 | goto out_dev_put; | 1475 | goto out_dev_put; |
| 1469 | } | 1476 | } |
| 1470 | 1477 | ||
| 1471 | if (!dev) | 1478 | if (dev == NULL) |
| 1472 | goto out; | 1479 | goto out_dev_put; |
| 1473 | 1480 | ||
| 1474 | n = neigh_lookup(tbl, RTA_DATA(dst_attr), dev); | 1481 | neigh = neigh_lookup(tbl, nla_data(dst_attr), dev); |
| 1475 | if (n) { | 1482 | if (neigh == NULL) { |
| 1476 | err = neigh_update(n, NULL, NUD_FAILED, | 1483 | err = -ENOENT; |
| 1477 | NEIGH_UPDATE_F_OVERRIDE| | 1484 | goto out_dev_put; |
| 1478 | NEIGH_UPDATE_F_ADMIN); | ||
| 1479 | neigh_release(n); | ||
| 1480 | } | 1485 | } |
| 1486 | |||
| 1487 | err = neigh_update(neigh, NULL, NUD_FAILED, | ||
| 1488 | NEIGH_UPDATE_F_OVERRIDE | | ||
| 1489 | NEIGH_UPDATE_F_ADMIN); | ||
| 1490 | neigh_release(neigh); | ||
| 1481 | goto out_dev_put; | 1491 | goto out_dev_put; |
| 1482 | } | 1492 | } |
| 1483 | read_unlock(&neigh_tbl_lock); | 1493 | read_unlock(&neigh_tbl_lock); |
| 1484 | err = -EADDRNOTAVAIL; | 1494 | err = -EAFNOSUPPORT; |
| 1495 | |||
| 1485 | out_dev_put: | 1496 | out_dev_put: |
| 1486 | if (dev) | 1497 | if (dev) |
| 1487 | dev_put(dev); | 1498 | dev_put(dev); |
| @@ -1491,76 +1502,93 @@ out: · 3 unmodified lines | |||
| 1491 | 1502 | ||
| 1492 | int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1503 | int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
| 1493 | { | 1504 | { |
| 1494 | struct ndmsg *ndm = NLMSG_DATA(nlh); | 1505 | struct ndmsg *ndm; |
| 1495 | struct rtattr **nda = arg; | 1506 | struct nlattr *tb[NDA_MAX+1]; |
| 1496 | struct neigh_table *tbl; | 1507 | struct neigh_table *tbl; |
| 1497 | struct net_device *dev = NULL; | 1508 | struct net_device *dev = NULL; |
| 1498 | int err = -ENODEV; | 1509 | int err; |
| 1499 | 1510 | ||
| 1500 | if (ndm->ndm_ifindex && | 1511 | err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); |
| 1501 | (dev = dev_get_by_index(ndm->ndm_ifindex)) == NULL) | 1512 | if (err < 0) |
| 1502 | goto out; | 1513 | goto out; |
| 1503 | 1514 | ||
| 1515 | err = -EINVAL; | ||
| 1516 | if (tb[NDA_DST] == NULL) | ||
| 1517 | goto out; | ||
| 1518 | |||
| 1519 | ndm = nlmsg_data(nlh); | ||
| 1520 | if (ndm->ndm_ifindex) { | ||
| 1521 | dev = dev_get_by_index(ndm->ndm_ifindex); | ||
| 1522 | if (dev == NULL) { | ||
| 1523 | err = -ENODEV; | ||
| 1524 | goto out; | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | if (tb[NDA_LLADDR] && nla_len(tb[NDA_LLADDR]) < dev->addr_len) | ||
| 1528 | goto out_dev_put; | ||
| 1529 | } | ||
| 1530 | |||
| 1504 | read_lock(&neigh_tbl_lock); | 1531 | read_lock(&neigh_tbl_lock); |
| 1505 | for (tbl = neigh_tables; tbl; tbl = tbl->next) { | 1532 | for (tbl = neigh_tables; tbl; tbl = tbl->next) { |
| 1506 | struct rtattr *lladdr_attr = nda[NDA_LLADDR - 1]; | 1533 | int flags = NEIGH_UPDATE_F_ADMIN | NEIGH_UPDATE_F_OVERRIDE; |
| 1507 | struct rtattr *dst_attr = nda[NDA_DST - 1]; | 1534 | struct neighbour *neigh; |
| 1508 | int override = 1; | 1535 | void *dst, *lladdr; |
| 1509 | struct neighbour *n; | ||
| 1510 | 1536 | ||
| 1511 | if (tbl->family != ndm->ndm_family) | 1537 | if (tbl->family != ndm->ndm_family) |
| 1512 | continue; | 1538 | continue; |
| 1513 | read_unlock(&neigh_tbl_lock); | 1539 | read_unlock(&neigh_tbl_lock); |
| 1514 | 1540 | ||
| 1515 | err = -EINVAL; | 1541 | if (nla_len(tb[NDA_DST]) < tbl->key_len) |
| 1516 | if (!dst_attr || RTA_PAYLOAD(dst_attr) < tbl->key_len) | ||
| 1517 | goto out_dev_put; | 1542 | goto out_dev_put; |
| 1543 | dst = nla_data(tb[NDA_DST]); | ||
| 1544 | lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL; | ||
| 1518 | 1545 | ||
| 1519 | if (ndm->ndm_flags & NTF_PROXY) { | 1546 | if (ndm->ndm_flags & NTF_PROXY) { |
| 1547 | struct pneigh_entry *pn; | ||
| 1548 | |||
| 1520 | err = -ENOBUFS; | 1549 | err = -ENOBUFS; |
| 1521 | if (pneigh_lookup(tbl, RTA_DATA(dst_attr), dev, 1)) | 1550 | pn = pneigh_lookup(tbl, dst, dev, 1); |
| 1551 | if (pn) { | ||
| 1552 | pn->flags = ndm->ndm_flags; | ||
| 1522 | err = 0; | 1553 | err = 0; |
| 1554 | } | ||
| 1523 | goto out_dev_put; | 1555 | goto out_dev_put; |
| 1524 | } | 1556 | } |
| 1525 | 1557 | ||
| 1526 | err = -EINVAL; | 1558 | if (dev == NULL) |
| 1527 | if (!dev) | ||
| 1528 | goto out; | ||
| 1529 | if (lladdr_attr && RTA_PAYLOAD(lladdr_attr) < dev->addr_len) | ||
| 1530 | goto out_dev_put; | 1559 | goto out_dev_put; |
| 1560 | |||
| 1561 | neigh = neigh_lookup(tbl, dst, dev); | ||
| 1562 | if (neigh == NULL) { | ||
| 1563 | if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { | ||
| 1564 | err = -ENOENT; | ||
| 1565 | goto out_dev_put; | ||
| 1566 | } | ||
| 1531 | 1567 | ||
| 1532 | n = neigh_lookup(tbl, RTA_DATA(dst_attr), dev); | 1568 | neigh = __neigh_lookup_errno(tbl, dst, dev); |
| 1533 | if (n) { | 1569 | if (IS_ERR(neigh)) { |
| 1534 | if (nlh->nlmsg_flags & NLM_F_EXCL) { | 1570 | err = PTR_ERR(neigh); |
| 1535 | err = -EEXIST; | ||
| 1536 | neigh_release(n); | ||
| 1537 | goto out_dev_put; | 1571 | goto out_dev_put; |
| 1538 | } | 1572 | } |
| 1539 | |||
| 1540 | override = nlh->nlmsg_flags & NLM_F_REPLACE; | ||
| 1541 | } else if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { | ||
| 1542 | err = -ENOENT; | ||
| 1543 | goto out_dev_put; | ||
| 1544 | } else { | 1573 | } else { |
| 1545 | n = __neigh_lookup_errno(tbl, RTA_DATA(dst_attr), dev); | 1574 | if (nlh->nlmsg_flags & NLM_F_EXCL) { |
| 1546 | if (IS_ERR(n)) { | 1575 | err = -EEXIST; |
| 1547 | err = PTR_ERR(n); | 1576 | neigh_release(neigh); |
| 1548 | goto out_dev_put; | 1577 | goto out_dev_put; |
| 1549 | } | 1578 | } |
| 1550 | } | ||
| 1551 | 1579 | ||
| 1552 | err = neigh_update(n, | 1580 | if (!(nlh->nlmsg_flags & NLM_F_REPLACE)) |
| 1553 | lladdr_attr ? RTA_DATA(lladdr_attr) : NULL, | 1581 | flags &= ~NEIGH_UPDATE_F_OVERRIDE; |
| 1554 | ndm->ndm_state, | 1582 | } |
| 1555 | (override ? NEIGH_UPDATE_F_OVERRIDE : 0) | | ||
| 1556 | NEIGH_UPDATE_F_ADMIN); | ||
| 1557 | 1583 | ||
| 1558 | neigh_release(n); | 1584 | err = neigh_update(neigh, lladdr, ndm->ndm_state, flags); |
| 1585 | neigh_release(neigh); | ||
| 1559 | goto out_dev_put; | 1586 | goto out_dev_put; |
| 1560 | } | 1587 | } |
| 1561 | 1588 | ||
| 1562 | read_unlock(&neigh_tbl_lock); | 1589 | read_unlock(&neigh_tbl_lock); |
| 1563 | err = -EADDRNOTAVAIL; | 1590 | err = -EAFNOSUPPORT; |
| 1591 | |||
| 1564 | out_dev_put: | 1592 | out_dev_put: |
| 1565 | if (dev) | 1593 | if (dev) |
| 1566 | dev_put(dev); | 1594 | dev_put(dev); |
| @@ -1570,56 +1598,59 @@ out: · 3 unmodified lines | |||
| 1570 | 1598 | ||
| 1571 | static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms) | 1599 | static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms) |
| 1572 | { | 1600 | { |
| 1573 | struct rtattr *nest = NULL; | 1601 | struct nlattr *nest; |
| 1574 | 1602 | ||
| 1575 | nest = RTA_NEST(skb, NDTA_PARMS); | 1603 | nest = nla_nest_start(skb, NDTA_PARMS); |
| 1604 | if (nest == NULL) | ||
| 1605 | return -ENOBUFS; | ||
| 1576 | 1606 | ||
| 1577 | if (parms->dev) | 1607 | if (parms->dev) |
| 1578 | RTA_PUT_U32(skb, NDTPA_IFINDEX, parms->dev->ifindex); | 1608 | NLA_PUT_U32(skb, NDTPA_IFINDEX, parms->dev->ifindex); |
| 1579 | 1609 | ||
| 1580 | RTA_PUT_U32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt)); | 1610 | NLA_PUT_U32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt)); |
| 1581 | RTA_PUT_U32(skb, NDTPA_QUEUE_LEN, parms->queue_len); | 1611 | NLA_PUT_U32(skb, NDTPA_QUEUE_LEN, parms->queue_len); |
| 1582 | RTA_PUT_U32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen); | 1612 | NLA_PUT_U32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen); |
| 1583 | RTA_PUT_U32(skb, NDTPA_APP_PROBES, parms->app_probes); | 1613 | NLA_PUT_U32(skb, NDTPA_APP_PROBES, parms->app_probes); |
| 1584 | RTA_PUT_U32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes); | 1614 | NLA_PUT_U32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes); |
| 1585 | RTA_PUT_U32(skb, NDTPA_MCAST_PROBES, parms->mcast_probes); | 1615 | NLA_PUT_U32(skb, NDTPA_MCAST_PROBES, parms->mcast_probes); |
| 1586 | RTA_PUT_MSECS(skb, NDTPA_REACHABLE_TIME, parms->reachable_time); | 1616 | NLA_PUT_MSECS(skb, NDTPA_REACHABLE_TIME, parms->reachable_time); |
| 1587 | RTA_PUT_MSECS(skb, NDTPA_BASE_REACHABLE_TIME, | 1617 | NLA_PUT_MSECS(skb, NDTPA_BASE_REACHABLE_TIME, |
| 1588 | parms->base_reachable_time); | 1618 | parms->base_reachable_time); |
| 1589 | RTA_PUT_MSECS(skb, NDTPA_GC_STALETIME, parms->gc_staletime); | 1619 | NLA_PUT_MSECS(skb, NDTPA_GC_STALETIME, parms->gc_staletime); |
| 1590 | RTA_PUT_MSECS(skb, NDTPA_DELAY_PROBE_TIME, parms->delay_probe_time); | 1620 | NLA_PUT_MSECS(skb, NDTPA_DELAY_PROBE_TIME, parms->delay_probe_time); |
| 1591 | RTA_PUT_MSECS(skb, NDTPA_RETRANS_TIME, parms->retrans_time); | 1621 | NLA_PUT_MSECS(skb, NDTPA_RETRANS_TIME, parms->retrans_time); |
| 1592 | RTA_PUT_MSECS(skb, NDTPA_ANYCAST_DELAY, parms->anycast_delay); | 1622 | NLA_PUT_MSECS(skb, NDTPA_ANYCAST_DELAY, parms->anycast_delay); |
| 1593 | RTA_PUT_MSECS(skb, NDTPA_PROXY_DELAY, parms->proxy_delay); | 1623 | NLA_PUT_MSECS(skb, NDTPA_PROXY_DELAY, parms->proxy_delay); |
| 1594 | RTA_PUT_MSECS(skb, NDTPA_LOCKTIME, parms->locktime); | 1624 | NLA_PUT_MSECS(skb, NDTPA_LOCKTIME, parms->locktime); |
| 1595 | 1625 | ||
| 1596 | return RTA_NEST_END(skb, nest); | 1626 | return nla_nest_end(skb, nest); |
| 1597 | 1627 | ||
| 1598 | rtattr_failure: | 1628 | nla_put_failure: |
| 1599 | return RTA_NEST_CANCEL(skb, nest); | 1629 | return nla_nest_cancel(skb, nest); |
| 1600 | } | 1630 | } |
| 1601 | 1631 | ||
| 1602 | static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, | 1632 | static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, |
| 1603 | struct netlink_callback *cb) | 1633 | u32 pid, u32 seq, int type, int flags) |
| 1604 | { | 1634 | { |
| 1605 | struct nlmsghdr *nlh; | 1635 | struct nlmsghdr *nlh; |
| 1606 | struct ndtmsg *ndtmsg; | 1636 | struct ndtmsg *ndtmsg; |
| 1607 | 1637 | ||
| 1608 | nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg), | 1638 | nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags); |
| 1609 | NLM_F_MULTI); | 1639 | if (nlh == NULL) |
| 1640 | return -ENOBUFS; | ||
| 1610 | 1641 | ||
| 1611 | ndtmsg = NLMSG_DATA(nlh); | 1642 | ndtmsg = nlmsg_data(nlh); |
| 1612 | 1643 | ||
| 1613 | read_lock_bh(&tbl->lock); | 1644 | read_lock_bh(&tbl->lock); |
| 1614 | ndtmsg->ndtm_family = tbl->family; | 1645 | ndtmsg->ndtm_family = tbl->family; |
| 1615 | ndtmsg->ndtm_pad1 = 0; | 1646 | ndtmsg->ndtm_pad1 = 0; |
| 1616 | ndtmsg->ndtm_pad2 = 0; | 1647 | ndtmsg->ndtm_pad2 = 0; |
| 1617 | 1648 | ||
| 1618 | RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); | 1649 | NLA_PUT_STRING(skb, NDTA_NAME, tbl->id); |
| 1619 | RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval); | 1650 | NLA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval); |
| 1620 | RTA_PUT_U32(skb, NDTA_THRESH1, tbl->gc_thresh1); | 1651 | NLA_PUT_U32(skb, NDTA_THRESH1, tbl->gc_thresh1); |
| 1621 | RTA_PUT_U32(skb, NDTA_THRESH2, tbl->gc_thresh2); | 1652 | NLA_PUT_U32(skb, NDTA_THRESH2, tbl->gc_thresh2); |
| 1622 | RTA_PUT_U32(skb, NDTA_THRESH3, tbl->gc_thresh3); | 1653 | NLA_PUT_U32(skb, NDTA_THRESH3, tbl->gc_thresh3); |
| 1623 | 1654 | ||
| 1624 | { | 1655 | { |
| 1625 | unsigned long now = jiffies; | 1656 | unsigned long now = jiffies; |
| @@ -1638,7 +1669,7 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, · 12 unmodified lines | |||
| 1638 | .ndtc_proxy_qlen = tbl->proxy_queue.qlen, | 1669 | .ndtc_proxy_qlen = tbl->proxy_queue.qlen, |
| 1639 | }; | 1670 | }; |
| 1640 | 1671 | ||
| 1641 | RTA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc); | 1672 | NLA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc); |
| 1642 | } | 1673 | } |
| 1643 | 1674 | ||
| 1644 | { | 1675 | { |
| @@ -1663,55 +1694,50 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, · 18 unmodified lines | |||
| 1663 | ndst.ndts_forced_gc_runs += st->forced_gc_runs; | 1694 | ndst.ndts_forced_gc_runs += st->forced_gc_runs; |
| 1664 | } | 1695 | } |
| 1665 | 1696 | ||
| 1666 | RTA_PUT(skb, NDTA_STATS, sizeof(ndst), &ndst); | 1697 | NLA_PUT(skb, NDTA_STATS, sizeof(ndst), &ndst); |
| 1667 | } | 1698 | } |
| 1668 | 1699 | ||
| 1669 | BUG_ON(tbl->parms.dev); | 1700 | BUG_ON(tbl->parms.dev); |
| 1670 | if (neightbl_fill_parms(skb, &tbl->parms) < 0) | 1701 | if (neightbl_fill_parms(skb, &tbl->parms) < 0) |
| 1671 | goto rtattr_failure; | 1702 | goto nla_put_failure; |
| 1672 | 1703 | ||
| 1673 | read_unlock_bh(&tbl->lock); | 1704 | read_unlock_bh(&tbl->lock); |
| 1674 | return NLMSG_END(skb, nlh); | 1705 | return nlmsg_end(skb, nlh); |
| 1675 | 1706 | ||
| 1676 | rtattr_failure: | 1707 | nla_put_failure: |
| 1677 | read_unlock_bh(&tbl->lock); | 1708 | read_unlock_bh(&tbl->lock); |
| 1678 | return NLMSG_CANCEL(skb, nlh); | 1709 | return nlmsg_cancel(skb, nlh); |
| 1679 | |||
| 1680 | nlmsg_failure: | ||
| 1681 | return -1; | ||
| 1682 | } | 1710 | } |
| 1683 | 1711 | ||
| 1684 | static int neightbl_fill_param_info(struct neigh_table *tbl, | 1712 | static int neightbl_fill_param_info(struct sk_buff *skb, |
| 1713 | struct neigh_table *tbl, | ||
| 1685 | struct neigh_parms *parms, | 1714 | struct neigh_parms *parms, |
| 1686 | struct sk_buff *skb, | 1715 | u32 pid, u32 seq, int type, |
| 1687 | struct netlink_callback *cb) | 1716 | unsigned int flags) |
| 1688 | { | 1717 | { |
| 1689 | struct ndtmsg *ndtmsg; | 1718 | struct ndtmsg *ndtmsg; |
| 1690 | struct nlmsghdr *nlh; | 1719 | struct nlmsghdr *nlh; |
| 1691 | 1720 | ||
| 1692 | nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg), | 1721 | nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags); |
| 1693 | NLM_F_MULTI); | 1722 | if (nlh == NULL) |
| 1723 | return -ENOBUFS; | ||
| 1694 | 1724 | ||
| 1695 | ndtmsg = NLMSG_DATA(nlh); | 1725 | ndtmsg = nlmsg_data(nlh); |
| 1696 | 1726 | ||
| 1697 | read_lock_bh(&tbl->lock); | 1727 | read_lock_bh(&tbl->lock); |
| 1698 | ndtmsg->ndtm_family = tbl->family; | 1728 | ndtmsg->ndtm_family = tbl->family; |
| 1699 | ndtmsg->ndtm_pad1 = 0; | 1729 | ndtmsg->ndtm_pad1 = 0; |
| 1700 | ndtmsg->ndtm_pad2 = 0; | 1730 | ndtmsg->ndtm_pad2 = 0; |
| 1701 | RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); | ||
| 1702 | 1731 | ||
| 1703 | if (neightbl_fill_parms(skb, parms) < 0) | 1732 | if (nla_put_string(skb, NDTA_NAME, tbl->id) < 0 || |
| 1704 | goto rtattr_failure; | 1733 | neightbl_fill_parms(skb, parms) < 0) |
| 1734 | goto errout; | ||
| 1705 | 1735 | ||
| 1706 | read_unlock_bh(&tbl->lock); | 1736 | read_unlock_bh(&tbl->lock); |
| 1707 | return NLMSG_END(skb, nlh); | 1737 | return nlmsg_end(skb, nlh); |
| 1708 | 1738 | errout: | |
| 1709 | rtattr_failure: | ||
| 1710 | read_unlock_bh(&tbl->lock); | 1739 | read_unlock_bh(&tbl->lock); |
| 1711 | return NLMSG_CANCEL(skb, nlh); | 1740 | return nlmsg_cancel(skb, nlh); |
| 1712 | |||
| 1713 | nlmsg_failure: | ||
| 1714 | return -1; | ||
| 1715 | } | 1741 | } |
| 1716 | 1742 | ||
| 1717 | static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, | 1743 | static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, |
| @@ -1727,28 +1753,61 @@ static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, · 9 unmodified lines | |||
| 1727 | return NULL; | 1753 | return NULL; |
| 1728 | } | 1754 | } |
| 1729 | 1755 | ||
| 1756 | static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = { | ||
| 1757 | [NDTA_NAME] = { .type = NLA_STRING }, | ||
| 1758 | [NDTA_THRESH1] = { .type = NLA_U32 }, | ||
| 1759 | [NDTA_THRESH2] = { .type = NLA_U32 }, | ||
| 1760 | [NDTA_THRESH3] = { .type = NLA_U32 }, | ||
| 1761 | [NDTA_GC_INTERVAL] = { .type = NLA_U64 }, | ||
| 1762 | [NDTA_PARMS] = { .type = NLA_NESTED }, | ||
| 1763 | }; | ||
| 1764 | |||
| 1765 | static struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] __read_mostly = { | ||
| 1766 | [NDTPA_IFINDEX] = { .type = NLA_U32 }, | ||
| 1767 | [NDTPA_QUEUE_LEN] = { .type = NLA_U32 }, | ||
| 1768 | [NDTPA_PROXY_QLEN] = { .type = NLA_U32 }, | ||
| 1769 | [NDTPA_APP_PROBES] = { .type = NLA_U32 }, | ||
| 1770 | [NDTPA_UCAST_PROBES] = { .type = NLA_U32 }, | ||
| 1771 | [NDTPA_MCAST_PROBES] = { .type = NLA_U32 }, | ||
| 1772 | [NDTPA_BASE_REACHABLE_TIME] = { .type = NLA_U64 }, | ||
| 1773 | [NDTPA_GC_STALETIME] = { .type = NLA_U64 }, | ||
| 1774 | [NDTPA_DELAY_PROBE_TIME] = { .type = NLA_U64 }, | ||
| 1775 | [NDTPA_RETRANS_TIME] = { .type = NLA_U64 }, | ||
| 1776 | [NDTPA_ANYCAST_DELAY] = { .type = NLA_U64 }, | ||
| 1777 | [NDTPA_PROXY_DELAY] = { .type = NLA_U64 }, | ||
| 1778 | [NDTPA_LOCKTIME] = { .type = NLA_U64 }, | ||
| 1779 | }; | ||
| 1780 | |||
| 1730 | int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1781 | int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
| 1731 | { | 1782 | { |
| 1732 | struct neigh_table *tbl; | 1783 | struct neigh_table *tbl; |
| 1733 | struct ndtmsg *ndtmsg = NLMSG_DATA(nlh); | 1784 | struct ndtmsg *ndtmsg; |
| 1734 | struct rtattr **tb = arg; | 1785 | struct nlattr *tb[NDTA_MAX+1]; |
| 1735 | int err = -EINVAL; | 1786 | int err; |
| 1736 | 1787 | ||
| 1737 | if (!tb[NDTA_NAME - 1] || !RTA_PAYLOAD(tb[NDTA_NAME - 1])) | 1788 | err = nlmsg_parse(nlh, sizeof(*ndtmsg), tb, NDTA_MAX, |
| 1738 | return -EINVAL; | 1789 | nl_neightbl_policy); |
| 1790 | if (err < 0) | ||
| 1791 | goto errout; | ||
| 1792 | |||
| 1793 | if (tb[NDTA_NAME] == NULL) { | ||
| 1794 | err = -EINVAL; | ||
| 1795 | goto errout; | ||
| 1796 | } | ||
| 1739 | 1797 | ||
| 1798 | ndtmsg = nlmsg_data(nlh); | ||
| 1740 | read_lock(&neigh_tbl_lock); | 1799 | read_lock(&neigh_tbl_lock); |
| 1741 | for (tbl = neigh_tables; tbl; tbl = tbl->next) { | 1800 | for (tbl = neigh_tables; tbl; tbl = tbl->next) { |
| 1742 | if (ndtmsg->ndtm_family && tbl->family != ndtmsg->ndtm_family) | 1801 | if (ndtmsg->ndtm_family && tbl->family != ndtmsg->ndtm_family) |
| 1743 | continue; | 1802 | continue; |
| 1744 | 1803 | ||
| 1745 | if (!rtattr_strcmp(tb[NDTA_NAME - 1], tbl->id)) | 1804 | if (nla_strcmp(tb[NDTA_NAME], tbl->id) == 0) |
| 1746 | break; | 1805 | break; |
| 1747 | } | 1806 | } |
| 1748 | 1807 | ||
| 1749 | if (tbl == NULL) { | 1808 | if (tbl == NULL) { |
| 1750 | err = -ENOENT; | 1809 | err = -ENOENT; |
| 1751 | goto errout; | 1810 | goto errout_locked; |
| 1752 | } | 1811 | } |
| 1753 | 1812 | ||
| 1754 | /* | 1813 | /* |
| @@ -1757,165 +1816,178 @@ int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) · 2 unmodified lines | |||
| 1757 | */ | 1816 | */ |
| 1758 | write_lock_bh(&tbl->lock); | 1817 | write_lock_bh(&tbl->lock); |
| 1759 | 1818 | ||
| 1760 | if (tb[NDTA_THRESH1 - 1]) | 1819 | if (tb[NDTA_PARMS]) { |
| 1761 | tbl->gc_thresh1 = RTA_GET_U32(tb[NDTA_THRESH1 - 1]); | 1820 | struct nlattr *tbp[NDTPA_MAX+1]; |
| 1762 | |||
| 1763 | if (tb[NDTA_THRESH2 - 1]) | ||
| 1764 | tbl->gc_thresh2 = RTA_GET_U32(tb[NDTA_THRESH2 - 1]); | ||
| 1765 | |||
| 1766 | if (tb[NDTA_THRESH3 - 1]) | ||
| 1767 | tbl->gc_thresh3 = RTA_GET_U32(tb[NDTA_THRESH3 - 1]); | ||
| 1768 | |||
| 1769 | if (tb[NDTA_GC_INTERVAL - 1]) | ||
| 1770 | tbl->gc_interval = RTA_GET_MSECS(tb[NDTA_GC_INTERVAL - 1]); | ||
| 1771 | |||
| 1772 | if (tb[NDTA_PARMS - 1]) { | ||
| 1773 | struct rtattr *tbp[NDTPA_MAX]; | ||
| 1774 | struct neigh_parms *p; | 1821 | struct neigh_parms *p; |
| 1775 | u32 ifindex = 0; | 1822 | int i, ifindex = 0; |
| 1776 | 1823 | ||
| 1777 | if (rtattr_parse_nested(tbp, NDTPA_MAX, tb[NDTA_PARMS - 1]) < 0) | 1824 | err = nla_parse_nested(tbp, NDTPA_MAX, tb[NDTA_PARMS], |
| 1778 | goto rtattr_failure; | 1825 | nl_ntbl_parm_policy); |
| 1826 | if (err < 0) | ||
| 1827 | goto errout_tbl_lock; | ||
| 1779 | 1828 | ||
| 1780 | if (tbp[NDTPA_IFINDEX - 1]) | 1829 | if (tbp[NDTPA_IFINDEX]) |
| 1781 | ifindex = RTA_GET_U32(tbp[NDTPA_IFINDEX - 1]); | 1830 | ifindex = nla_get_u32(tbp[NDTPA_IFINDEX]); |
| 1782 | 1831 | ||
| 1783 | p = lookup_neigh_params(tbl, ifindex); | 1832 | p = lookup_neigh_params(tbl, ifindex); |
| 1784 | if (p == NULL) { | 1833 | if (p == NULL) { |
| 1785 | err = -ENOENT; | 1834 | err = -ENOENT; |
| 1786 | goto rtattr_failure; | 1835 | goto errout_tbl_lock; |
| 1787 | } | 1836 | } |
| 1788 | |||
| 1789 | if (tbp[NDTPA_QUEUE_LEN - 1]) | ||
| 1790 | p->queue_len = RTA_GET_U32(tbp[NDTPA_QUEUE_LEN - 1]); | ||
| 1791 | |||
| 1792 | if (tbp[NDTPA_PROXY_QLEN - 1]) | ||
| 1793 | p->proxy_qlen = RTA_GET_U32(tbp[NDTPA_PROXY_QLEN - 1]); | ||
| 1794 | |||
| 1795 | if (tbp[NDTPA_APP_PROBES - 1]) | ||
| 1796 | p->app_probes = RTA_GET_U32(tbp[NDTPA_APP_PROBES - 1]); | ||
| 1797 | 1837 | ||
| 1798 | if (tbp[NDTPA_UCAST_PROBES - 1]) | 1838 | for (i = 1; i <= NDTPA_MAX; i++) { |
| 1799 | p->ucast_probes = | 1839 | if (tbp[i] == NULL) |
| 1800 | RTA_GET_U32(tbp[NDTPA_UCAST_PROBES - 1]); | 1840 | continue; |
| 1801 | |||
| 1802 | if (tbp[NDTPA_MCAST_PROBES - 1]) | ||
| 1803 | p->mcast_probes = | ||
| 1804 | RTA_GET_U32(tbp[NDTPA_MCAST_PROBES - 1]); | ||
| 1805 | |||
| 1806 | if (tbp[NDTPA_BASE_REACHABLE_TIME - 1]) | ||
| 1807 | p->base_reachable_time = | ||
| 1808 | RTA_GET_MSECS(tbp[NDTPA_BASE_REACHABLE_TIME - 1]); | ||
| 1809 | |||
| 1810 | if (tbp[NDTPA_GC_STALETIME - 1]) | ||
| 1811 | p->gc_staletime = | ||
| 1812 | RTA_GET_MSECS(tbp[NDTPA_GC_STALETIME - 1]); | ||
| 1813 | 1841 | ||
| 1814 | if (tbp[NDTPA_DELAY_PROBE_TIME - 1]) | 1842 | switch (i) { |
| 1815 | p->delay_probe_time = | 1843 | case NDTPA_QUEUE_LEN: |
| 1816 | RTA_GET_MSECS(tbp[NDTPA_DELAY_PROBE_TIME - 1]); | 1844 | p->queue_len = nla_get_u32(tbp[i]); |
| 1845 | break; | ||
| 1846 | case NDTPA_PROXY_QLEN: | ||
| 1847 | p->proxy_qlen = nla_get_u32(tbp[i]); | ||
| 1848 | break; | ||
| 1849 | case NDTPA_APP_PROBES: | ||
| 1850 | p->app_probes = nla_get_u32(tbp[i]); | ||
| 1851 | break; | ||
| 1852 | case NDTPA_UCAST_PROBES: | ||
| 1853 | p->ucast_probes = nla_get_u32(tbp[i]); | ||
| 1854 | break; | ||
| 1855 | case NDTPA_MCAST_PROBES: | ||
| 1856 | p->mcast_probes = nla_get_u32(tbp[i]); | ||
| 1857 | break; | ||
| 1858 | case NDTPA_BASE_REACHABLE_TIME: | ||
| 1859 | p->base_reachable_time = nla_get_msecs(tbp[i]); | ||
| 1860 | break; | ||
| 1861 | case NDTPA_GC_STALETIME: | ||
| 1862 | p->gc_staletime = nla_get_msecs(tbp[i]); | ||
| 1863 | break; | ||
| 1864 | case NDTPA_DELAY_PROBE_TIME: | ||
| 1865 | p->delay_probe_time = nla_get_msecs(tbp[i]); | ||
| 1866 | break; | ||
| 1867 | case NDTPA_RETRANS_TIME: | ||
| 1868 | p->retrans_time = nla_get_msecs(tbp[i]); | ||
| 1869 | break; | ||
| 1870 | case NDTPA_ANYCAST_DELAY: | ||
| 1871 | p->anycast_delay = nla_get_msecs(tbp[i]); | ||
| 1872 | break; | ||
| 1873 | case NDTPA_PROXY_DELAY: | ||
| 1874 | p->proxy_delay = nla_get_msecs(tbp[i]); | ||
| 1875 | break; | ||
| 1876 | case NDTPA_LOCKTIME: | ||
| 1877 | p->locktime = nla_get_msecs(tbp[i]); | ||
| 1878 | break; | ||
| 1879 | } | ||
| 1880 | } | ||
| 1881 | } | ||
| 1817 | 1882 | ||
| 1818 | if (tbp[NDTPA_RETRANS_TIME - 1]) | 1883 | if (tb[NDTA_THRESH1]) |
| 1819 | p->retrans_time = | 1884 | tbl->gc_thresh1 = nla_get_u32(tb[NDTA_THRESH1]); |
| 1820 | RTA_GET_MSECS(tbp[NDTPA_RETRANS_TIME - 1]); | ||
| 1821 | 1885 | ||
| 1822 | if (tbp[NDTPA_ANYCAST_DELAY - 1]) | 1886 | if (tb[NDTA_THRESH2]) |
| 1823 | p->anycast_delay = | 1887 | tbl->gc_thresh2 = nla_get_u32(tb[NDTA_THRESH2]); |
| 1824 | RTA_GET_MSECS(tbp[NDTPA_ANYCAST_DELAY - 1]); | ||
| 1825 | 1888 | ||
| 1826 | if (tbp[NDTPA_PROXY_DELAY - 1]) | 1889 | if (tb[NDTA_THRESH3]) |
| 1827 | p->proxy_delay = | 1890 | tbl->gc_thresh3 = nla_get_u32(tb[NDTA_THRESH3]); |
| 1828 | RTA_GET_MSECS(tbp[NDTPA_PROXY_DELAY - 1]); | ||
| 1829 | 1891 | ||
| 1830 | if (tbp[NDTPA_LOCKTIME - 1]) | 1892 | if (tb[NDTA_GC_INTERVAL]) |
| 1831 | p->locktime = RTA_GET_MSECS(tbp[NDTPA_LOCKTIME - 1]); | 1893 | tbl->gc_interval = nla_get_msecs(tb[NDTA_GC_INTERVAL]); |
| 1832 | } | ||
| 1833 | 1894 | ||
| 1834 | err = 0; | 1895 | err = 0; |
| 1835 | 1896 | ||
| 1836 | rtattr_failure: | 1897 | errout_tbl_lock: |
| 1837 | write_unlock_bh(&tbl->lock); | 1898 | write_unlock_bh(&tbl->lock); |
| 1838 | errout: | 1899 | errout_locked: |
| 1839 | read_unlock(&neigh_tbl_lock); | 1900 | read_unlock(&neigh_tbl_lock); |
| 1901 | errout: | ||
| 1840 | return err; | 1902 | return err; |
| 1841 | } | 1903 | } |
| 1842 | 1904 | ||
| 1843 | int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) | 1905 | int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) |
| 1844 | { | 1906 | { |
| 1845 | int idx, family; | 1907 | int family, tidx, nidx = 0; |
| 1846 | int s_idx = cb->args[0]; | 1908 | int tbl_skip = cb->args[0]; |
| 1909 | int neigh_skip = cb->args[1]; | ||
| 1847 | struct neigh_table *tbl; | 1910 | struct neigh_table *tbl; |
| 1848 | 1911 | ||
| 1849 | family = ((struct rtgenmsg *)NLMSG_DATA(cb->nlh))->rtgen_family; | 1912 | family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family; |
| 1850 | 1913 | ||
| 1851 | read_lock(&neigh_tbl_lock); | 1914 | read_lock(&neigh_tbl_lock); |
| 1852 | for (tbl = neigh_tables, idx = 0; tbl; tbl = tbl->next) { | 1915 | for (tbl = neigh_tables, tidx = 0; tbl; tbl = tbl->next, tidx++) { |
| 1853 | struct neigh_parms *p; | 1916 | struct neigh_parms *p; |
| 1854 | 1917 | ||
| 1855 | if (idx < s_idx || (family && tbl->family != family)) | 1918 | if (tidx < tbl_skip || (family && tbl->family != family)) |
| 1856 | continue; | 1919 | continue; |
| 1857 | 1920 | ||
| 1858 | if (neightbl_fill_info(tbl, skb, cb) <= 0) | 1921 | if (neightbl_fill_info(skb, tbl, NETLINK_CB(cb->skb).pid, |
| 1922 | cb->nlh->nlmsg_seq, RTM_NEWNEIGHTBL, | ||
| 1923 | NLM_F_MULTI) <= 0) | ||
| 1859 | break; | 1924 | break; |
| 1860 | 1925 | ||
| 1861 | for (++idx, p = tbl->parms.next; p; p = p->next, idx++) { | 1926 | for (nidx = 0, p = tbl->parms.next; p; p = p->next, nidx++) { |
| 1862 | if (idx < s_idx) | 1927 | if (nidx < neigh_skip) |
| 1863 | continue; | 1928 | continue; |
| 1864 | 1929 | ||
| 1865 | if (neightbl_fill_param_info(tbl, p, skb, cb) <= 0) | 1930 | if (neightbl_fill_param_info(skb, tbl, p, |
| 1931 | NETLINK_CB(cb->skb).pid, | ||
| 1932 | cb->nlh->nlmsg_seq, | ||
| 1933 | RTM_NEWNEIGHTBL, | ||
| 1934 | NLM_F_MULTI) <= 0) | ||
| 1866 | goto out; | 1935 | goto out; |
| 1867 | } | 1936 | } |
| 1868 | 1937 | ||
| 1938 | neigh_skip = 0; | ||
| 1869 | } | 1939 | } |
| 1870 | out: | 1940 | out: |
| 1871 | read_unlock(&neigh_tbl_lock); | 1941 | read_unlock(&neigh_tbl_lock); |
| 1872 | cb->args[0] = idx; | 1942 | cb->args[0] = tidx; |
| 1943 | cb->args[1] = nidx; | ||
| 1873 | 1944 | ||
| 1874 | return skb->len; | 1945 | return skb->len; |
| 1875 | } | 1946 | } |
| 1876 | 1947 | ||
| 1877 | static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n, | 1948 | static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh, |
| 1878 | u32 pid, u32 seq, int event, unsigned int flags) | 1949 | u32 pid, u32 seq, int type, unsigned int flags) |
| 1879 | { | 1950 | { |
| 1880 | unsigned long now = jiffies; | 1951 | unsigned long now = jiffies; |
| 1881 | unsigned char *b = skb->tail; | ||
| 1882 | struct nda_cacheinfo ci; | 1952 | struct nda_cacheinfo ci; |
| 1883 | int locked = 0; | 1953 | struct nlmsghdr *nlh; |
| 1884 | u32 probes; | 1954 | struct ndmsg *ndm; |
| 1885 | struct nlmsghdr *nlh = NLMSG_NEW(skb, pid, seq, event, | 1955 | |
| 1886 | sizeof(struct ndmsg), flags); | 1956 | nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags); |
| 1887 | struct ndmsg *ndm = NLMSG_DATA(nlh); | 1957 | if (nlh == NULL) |
| 1958 | return -ENOBUFS; | ||
| 1888 | 1959 | ||
| 1889 | ndm->ndm_family = n->ops->family; | 1960 | ndm = nlmsg_data(nlh); |
| 1961 | ndm->ndm_family = neigh->ops->family; | ||
| 1890 | ndm->ndm_pad1 = 0; | 1962 | ndm->ndm_pad1 = 0; |
| 1891 | ndm->ndm_pad2 = 0; | 1963 | ndm->ndm_pad2 = 0; |
| 1892 | ndm->ndm_flags = n->flags; | 1964 | ndm->ndm_flags = neigh->flags; |
| 1893 | ndm->ndm_type = n->type; | 1965 | ndm->ndm_type = neigh->type; |
| 1894 | ndm->ndm_ifindex = n->dev->ifindex; | 1966 | ndm->ndm_ifindex = neigh->dev->ifindex; |
| 1895 | RTA_PUT(skb, NDA_DST, n->tbl->key_len, n->primary_key); | 1967 | |
| 1896 | read_lock_bh(&n->lock); | 1968 | NLA_PUT(skb, NDA_DST, neigh->tbl->key_len, neigh->primary_key); |
| 1897 | locked = 1; | ||
| 1898 | ndm->ndm_state = n->nud_state; | ||
| 1899 | if (n->nud_state & NUD_VALID) | ||
| 1900 | RTA_PUT(skb, NDA_LLADDR, n->dev->addr_len, n->ha); | ||
| 1901 | ci.ndm_used = now - n->used; | ||
| 1902 | ci.ndm_confirmed = now - n->confirmed; | ||
| 1903 | ci.ndm_updated = now - n->updated; | ||
| 1904 | ci.ndm_refcnt = atomic_read(&n->refcnt) - 1; | ||
| 1905 | probes = atomic_read(&n->probes); | ||
| 1906 | read_unlock_bh(&n->lock); | ||
| 1907 | locked = 0; | ||
| 1908 | RTA_PUT(skb, NDA_CACHEINFO, sizeof(ci), &ci); | ||
| 1909 | RTA_PUT(skb, NDA_PROBES, sizeof(probes), &probes); | ||
| 1910 | nlh->nlmsg_len = skb->tail - b; | ||
| 1911 | return skb->len; | ||
| 1912 | 1969 | ||
| 1913 | nlmsg_failure: | 1970 | read_lock_bh(&neigh->lock); |
| 1914 | rtattr_failure: | 1971 | ndm->ndm_state = neigh->nud_state; |
| 1915 | if (locked) | 1972 | if ((neigh->nud_state & NUD_VALID) && |
| 1916 | read_unlock_bh(&n->lock); | 1973 | nla_put(skb, NDA_LLADDR, neigh->dev->addr_len, neigh->ha) < 0) { |
| 1917 | skb_trim(skb, b - skb->data); | 1974 | read_unlock_bh(&neigh->lock); |
| 1918 | return -1; | 1975 | goto nla_put_failure; |
| 1976 | } | ||
| 1977 | |||
| 1978 | ci.ndm_used = now - neigh->used; | ||
| 1979 | ci.ndm_confirmed = now - neigh->confirmed; | ||
| 1980 | ci.ndm_updated = now - neigh->updated; | ||
| 1981 | ci.ndm_refcnt = atomic_read(&neigh->refcnt) - 1; | ||
| 1982 | read_unlock_bh(&neigh->lock); | ||
| 1983 | |||
| 1984 | NLA_PUT_U32(skb, NDA_PROBES, atomic_read(&neigh->probes)); | ||
| 1985 | NLA_PUT(skb, NDA_CACHEINFO, sizeof(ci), &ci); | ||
| 1986 | |||
| 1987 | return nlmsg_end(skb, nlh); | ||
| 1988 | |||
| 1989 | nla_put_failure: | ||
| 1990 | return nlmsg_cancel(skb, nlh); | ||
| 1919 | } | 1991 | } |
| 1920 | 1992 | ||
| 1921 | 1993 | ||
| @@ -1959,7 +2031,7 @@ int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb) · 37 unmodified lines | |||
| 1959 | int t, family, s_t; | 2031 | int t, family, s_t; |
| 1960 | 2032 | ||
| 1961 | read_lock(&neigh_tbl_lock); | 2033 | read_lock(&neigh_tbl_lock); |
| 1962 | family = ((struct rtgenmsg *)NLMSG_DATA(cb->nlh))->rtgen_family; | 2034 | family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family; |
| 1963 | s_t = cb->args[0]; | 2035 | s_t = cb->args[0]; |
| 1964 | 2036 | ||
| 1965 | for (tbl = neigh_tables, t = 0; tbl; tbl = tbl->next, t++) { | 2037 | for (tbl = neigh_tables, t = 0; tbl; tbl = tbl->next, t++) { |
| @@ -2338,41 +2410,35 @@ static struct file_operations neigh_stat_seq_fops = { · 372 unmodified lines | |||
| 2338 | #endif /* CONFIG_PROC_FS */ | 2410 | #endif /* CONFIG_PROC_FS */ |
| 2339 | 2411 | ||
| 2340 | #ifdef CONFIG_ARPD | 2412 | #ifdef CONFIG_ARPD |
| 2341 | void neigh_app_ns(struct neighbour *n) | 2413 | static void __neigh_notify(struct neighbour *n, int type, int flags) |
| 2342 | { | 2414 | { |
| 2343 | struct nlmsghdr *nlh; | 2415 | struct sk_buff *skb; |
| 2344 | int size = NLMSG_SPACE(sizeof(struct ndmsg) + 256); | 2416 | int err = -ENOBUFS; |
| 2345 | struct sk_buff *skb = alloc_skb(size, GFP_ATOMIC); | ||
| 2346 | 2417 | ||
| 2347 | if (!skb) | 2418 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); |
| 2348 | return; | 2419 | if (skb == NULL) |
| 2420 | goto errout; | ||
| 2349 | 2421 | ||
| 2350 | if (neigh_fill_info(skb, n, 0, 0, RTM_GETNEIGH, 0) < 0) { | 2422 | err = neigh_fill_info(skb, n, 0, 0, type, flags); |
| 2423 | if (err < 0) { | ||
| 2351 | kfree_skb(skb); | 2424 | kfree_skb(skb); |
| 2352 | return; | 2425 | goto errout; |
| 2353 | } | 2426 | } |
| 2354 | nlh = (struct nlmsghdr *)skb->data; | 2427 | |
| 2355 | nlh->nlmsg_flags = NLM_F_REQUEST; | 2428 | err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); |
| 2356 | NETLINK_CB(skb).dst_group = RTNLGRP_NEIGH; | 2429 | errout: |
| 2357 | netlink_broadcast(rtnl, skb, 0, RTNLGRP_NEIGH, GFP_ATOMIC); | 2430 | if (err < 0) |
| 2431 | rtnl_set_sk_err(RTNLGRP_NEIGH, err); | ||
| 2358 | } | 2432 | } |
| 2359 | 2433 | ||
| 2360 | static void neigh_app_notify(struct neighbour *n) | 2434 | void neigh_app_ns(struct neighbour *n) |
| 2361 | { | 2435 | { |
| 2362 | struct nlmsghdr *nlh; | 2436 | __neigh_notify(n, RTM_GETNEIGH, NLM_F_REQUEST); |
| 2363 | int size = NLMSG_SPACE(sizeof(struct ndmsg) + 256); | 2437 | } |
| 2364 | struct sk_buff *skb = alloc_skb(size, GFP_ATOMIC); | ||
| 2365 | |||
| 2366 | if (!skb) | ||
| 2367 | return; | ||
| 2368 | 2438 | ||
| 2369 | if (neigh_fill_info(skb, n, 0, 0, RTM_NEWNEIGH, 0) < 0) { | 2439 | static void neigh_app_notify(struct neighbour *n) |
| 2370 | kfree_skb(skb); | 2440 | { |
| 2371 | return; | 2441 | __neigh_notify(n, RTM_NEWNEIGH, 0); |
| 2372 | } | ||
| 2373 | nlh = (struct nlmsghdr *)skb->data; | ||
| 2374 | NETLINK_CB(skb).dst_group = RTNLGRP_NEIGH; | ||
| 2375 | netlink_broadcast(rtnl, skb, 0, RTNLGRP_NEIGH, GFP_ATOMIC); | ||
| 2376 | } | 2442 | } |
| 2377 | 2443 | ||
| 2378 | #endif /* CONFIG_ARPD */ | 2444 | #endif /* CONFIG_ARPD */ |
| @@ -2386,7 +2452,7 @@ static struct neigh_sysctl_table { · 7 unmodified lines | |||
| 2386 | ctl_table neigh_neigh_dir[2]; | 2452 | ctl_table neigh_neigh_dir[2]; |
| 2387 | ctl_table neigh_proto_dir[2]; | 2453 | ctl_table neigh_proto_dir[2]; |
| 2388 | ctl_table neigh_root_dir[2]; | 2454 | ctl_table neigh_root_dir[2]; |
| 2389 | } neigh_sysctl_template = { | 2455 | } neigh_sysctl_template __read_mostly = { |
| 2390 | .neigh_vars = { | 2456 | .neigh_vars = { |
| 2391 | { | 2457 | { |
| 2392 | .ctl_name = NET_NEIGH_MCAST_SOLICIT, | 2458 | .ctl_name = NET_NEIGH_MCAST_SOLICIT, |
| @@ -2659,7 +2725,6 @@ void neigh_sysctl_unregister(struct neigh_parms *p) · 266 unmodified lines | |||
| 2659 | #endif /* CONFIG_SYSCTL */ | 2725 | #endif /* CONFIG_SYSCTL */ |
| 2660 | 2726 | ||
| 2661 | EXPORT_SYMBOL(__neigh_event_send); | 2727 | EXPORT_SYMBOL(__neigh_event_send); |
| 2662 | EXPORT_SYMBOL(neigh_add); | ||
| 2663 | EXPORT_SYMBOL(neigh_changeaddr); | 2728 | EXPORT_SYMBOL(neigh_changeaddr); |
| 2664 | EXPORT_SYMBOL(neigh_compat_output); | 2729 | EXPORT_SYMBOL(neigh_compat_output); |
| 2665 | EXPORT_SYMBOL(neigh_connected_output); | 2730 | EXPORT_SYMBOL(neigh_connected_output); |
| @@ -2679,11 +2744,8 @@ EXPORT_SYMBOL(neigh_table_clear); · 13 unmodified lines | |||
| 2679 | EXPORT_SYMBOL(neigh_table_init); | 2744 | EXPORT_SYMBOL(neigh_table_init); |
| 2680 | EXPORT_SYMBOL(neigh_table_init_no_netlink); | 2745 | EXPORT_SYMBOL(neigh_table_init_no_netlink); |
| 2681 | EXPORT_SYMBOL(neigh_update); | 2746 | EXPORT_SYMBOL(neigh_update); |
| 2682 | EXPORT_SYMBOL(neigh_update_hhs); | ||
| 2683 | EXPORT_SYMBOL(pneigh_enqueue); | 2747 | EXPORT_SYMBOL(pneigh_enqueue); |
| 2684 | EXPORT_SYMBOL(pneigh_lookup); | 2748 | EXPORT_SYMBOL(pneigh_lookup); |
| 2685 | EXPORT_SYMBOL(neightbl_dump_info); | ||
| 2686 | EXPORT_SYMBOL(neightbl_set); | ||
| 2687 | 2749 | ||
| 2688 | #ifdef CONFIG_ARPD | 2750 | #ifdef CONFIG_ARPD |
| 2689 | EXPORT_SYMBOL(neigh_app_ns); | 2751 | EXPORT_SYMBOL(neigh_app_ns); |
| @@ -110,7 +110,7 @@ static int checksum_udp(struct sk_buff *skb, struct udphdr *uh, · 109 unmodified lines | |||
| 110 | 110 | ||
| 111 | psum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0); | 111 | psum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0); |
| 112 | 112 | ||
| 113 | if (skb->ip_summed == CHECKSUM_HW && | 113 | if (skb->ip_summed == CHECKSUM_COMPLETE && |
| 114 | !(u16)csum_fold(csum_add(psum, skb->csum))) | 114 | !(u16)csum_fold(csum_add(psum, skb->csum))) |
| 115 | return 0; | 115 | return 0; |
| 116 | 116 | ||
| @@ -1786,7 +1786,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) · 1785 unmodified lines | |||
| 1786 | * use ipv6_get_lladdr if/when it's get exported | 1786 | * use ipv6_get_lladdr if/when it's get exported |
| 1787 | */ | 1787 | */ |
| 1788 | 1788 | ||
| 1789 | read_lock(&addrconf_lock); | 1789 | rcu_read_lock(); |
| 1790 | if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) { | 1790 | if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) { |
| 1791 | struct inet6_ifaddr *ifp; | 1791 | struct inet6_ifaddr *ifp; |
| 1792 | 1792 | ||
| @@ -1805,7 +1805,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) · 12 unmodified lines | |||
| 1805 | } | 1805 | } |
| 1806 | read_unlock_bh(&idev->lock); | 1806 | read_unlock_bh(&idev->lock); |
| 1807 | } | 1807 | } |
| 1808 | read_unlock(&addrconf_lock); | 1808 | rcu_read_unlock(); |
| 1809 | if (err) | 1809 | if (err) |
| 1810 | printk("pktgen: ERROR: IPv6 link address not availble.\n"); | 1810 | printk("pktgen: ERROR: IPv6 link address not availble.\n"); |
| 1811 | } | 1811 | } |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | |||
| 35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
| 36 | #include <linux/security.h> | 36 | #include <linux/security.h> |
| 37 | #include <linux/mutex.h> | 37 | #include <linux/mutex.h> |
| 38 | #include <linux/if_addr.h> | ||
| 38 | 39 | ||
| 39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
| 40 | #include <asm/system.h> | 41 | #include <asm/system.h> |
| @@ -49,6 +50,7 @@ · 8 unmodified lines | |||
| 49 | #include <net/udp.h> | 50 | #include <net/udp.h> |
| 50 | #include <net/sock.h> | 51 | #include <net/sock.h> |
| 51 | #include <net/pkt_sched.h> | 52 | #include <net/pkt_sched.h> |
| 53 | #include <net/fib_rules.h> | ||
| 52 | #include <net/netlink.h> | 54 | #include <net/netlink.h> |
| 53 | #ifdef CONFIG_NET_WIRELESS_RTNETLINK | 55 | #ifdef CONFIG_NET_WIRELESS_RTNETLINK |
| 54 | #include <linux/wireless.h> | 56 | #include <linux/wireless.h> |
| @@ -56,6 +58,7 @@ · 1 unmodified line | |||
| 56 | #endif /* CONFIG_NET_WIRELESS_RTNETLINK */ | 58 | #endif /* CONFIG_NET_WIRELESS_RTNETLINK */ |
| 57 | 59 | ||
| 58 | static DEFINE_MUTEX(rtnl_mutex); | 60 | static DEFINE_MUTEX(rtnl_mutex); |
| 61 | static struct sock *rtnl; | ||
| 59 | 62 | ||
| 60 | void rtnl_lock(void) | 63 | void rtnl_lock(void) |
| 61 | { | 64 | { |
| @@ -93,8 +96,6 @@ int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len) · 31 unmodified lines | |||
| 93 | return 0; | 96 | return 0; |
| 94 | } | 97 | } |
| 95 | 98 | ||
| 96 | struct sock *rtnl; | ||
| 97 | |||
| 98 | struct rtnetlink_link * rtnetlink_links[NPROTO]; | 99 | struct rtnetlink_link * rtnetlink_links[NPROTO]; |
| 99 | 100 | ||
| 100 | static const int rtm_min[RTM_NR_FAMILIES] = | 101 | static const int rtm_min[RTM_NR_FAMILIES] = |
| @@ -102,8 +103,7 @@ static const int rtm_min[RTM_NR_FAMILIES] = · 1 unmodified line | |||
| 102 | [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)), | 103 | [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)), |
| 103 | [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), | 104 | [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), |
| 104 | [RTM_FAM(RTM_NEWROUTE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), | 105 | [RTM_FAM(RTM_NEWROUTE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), |
| 105 | [RTM_FAM(RTM_NEWNEIGH)] = NLMSG_LENGTH(sizeof(struct ndmsg)), | 106 | [RTM_FAM(RTM_NEWRULE)] = NLMSG_LENGTH(sizeof(struct fib_rule_hdr)), |
| 106 | [RTM_FAM(RTM_NEWRULE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), | ||
| 107 | [RTM_FAM(RTM_NEWQDISC)] = NLMSG_LENGTH(sizeof(struct tcmsg)), | 107 | [RTM_FAM(RTM_NEWQDISC)] = NLMSG_LENGTH(sizeof(struct tcmsg)), |
| 108 | [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)), | 108 | [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)), |
| 109 | [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)), | 109 | [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)), |
| @@ -111,7 +111,6 @@ static const int rtm_min[RTM_NR_FAMILIES] = · 1 unmodified line | |||
| 111 | [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | 111 | [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), |
| 112 | [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | 112 | [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), |
| 113 | [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | 113 | [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), |
| 114 | [RTM_FAM(RTM_NEWNEIGHTBL)] = NLMSG_LENGTH(sizeof(struct ndtmsg)), | ||
| 115 | }; | 114 | }; |
| 116 | 115 | ||
| 117 | static const int rta_max[RTM_NR_FAMILIES] = | 116 | static const int rta_max[RTM_NR_FAMILIES] = |
| @@ -119,13 +118,11 @@ static const int rta_max[RTM_NR_FAMILIES] = · 1 unmodified line | |||
| 119 | [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX, | 118 | [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX, |
| 120 | [RTM_FAM(RTM_NEWADDR)] = IFA_MAX, | 119 | [RTM_FAM(RTM_NEWADDR)] = IFA_MAX, |
| 121 | [RTM_FAM(RTM_NEWROUTE)] = RTA_MAX, | 120 | [RTM_FAM(RTM_NEWROUTE)] = RTA_MAX, |
| 122 | [RTM_FAM(RTM_NEWNEIGH)] = NDA_MAX, | 121 | [RTM_FAM(RTM_NEWRULE)] = FRA_MAX, |
| 123 | [RTM_FAM(RTM_NEWRULE)] = RTA_MAX, | ||
| 124 | [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX, | 122 | [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX, |
| 125 | [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX, | 123 | [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX, |
| 126 | [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX, | 124 | [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX, |
| 127 | [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX, | 125 | [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX, |
| 128 | [RTM_FAM(RTM_NEWNEIGHTBL)] = NDTA_MAX, | ||
| 129 | }; | 126 | }; |
| 130 | 127 | ||
| 131 | void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) | 128 | void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) |
| @@ -168,24 +165,52 @@ int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo) · 36 unmodified lines | |||
| 168 | return err; | 165 | return err; |
| 169 | } | 166 | } |
| 170 | 167 | ||
| 168 | int rtnl_unicast(struct sk_buff *skb, u32 pid) | ||
| 169 | { | ||
| 170 | return nlmsg_unicast(rtnl, skb, pid); | ||
| 171 | } | ||
| 172 | |||
| 173 | int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group, | ||
| 174 | struct nlmsghdr *nlh, gfp_t flags) | ||
| 175 | { | ||
| 176 | int report = 0; | ||
| 177 | |||
| 178 | if (nlh) | ||
| 179 | report = nlmsg_report(nlh); | ||
| 180 | |||
| 181 | return nlmsg_notify(rtnl, skb, pid, group, report, flags); | ||
| 182 | } | ||
| 183 | |||
| 184 | void rtnl_set_sk_err(u32 group, int error) | ||
| 185 | { | ||
| 186 | netlink_set_err(rtnl, 0, group, error); | ||
| 187 | } | ||
| 188 | |||
| 171 | int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics) | 189 | int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics) |
| 172 | { | 190 | { |
| 173 | struct rtattr *mx = (struct rtattr*)skb->tail; | 191 | struct nlattr *mx; |
| 174 | int i; | 192 | int i, valid = 0; |
| 193 | |||
| 194 | mx = nla_nest_start(skb, RTA_METRICS); | ||
| 195 | if (mx == NULL) | ||
| 196 | return -ENOBUFS; | ||
| 197 | |||
| 198 | for (i = 0; i < RTAX_MAX; i++) { | ||
| 199 | if (metrics[i]) { | ||
| 200 | valid++; | ||
| 201 | NLA_PUT_U32(skb, i+1, metrics[i]); | ||
| 202 | } | ||
| 203 | } | ||
| 175 | 204 | ||
| 176 | RTA_PUT(skb, RTA_METRICS, 0, NULL); | 205 | if (!valid) { |
| 177 | for (i=0; i<RTAX_MAX; i++) { | 206 | nla_nest_cancel(skb, mx); |
| 178 | if (metrics[i]) | 207 | return 0; |
| 179 | RTA_PUT(skb, i+1, sizeof(u32), metrics+i); | ||
| 180 | } | 208 | } |
| 181 | mx->rta_len = skb->tail - (u8*)mx; | ||
| 182 | if (mx->rta_len == RTA_LENGTH(0)) | ||
| 183 | skb_trim(skb, (u8*)mx - skb->data); | ||
| 184 | return 0; | ||
| 185 | 209 | ||
| 186 | rtattr_failure: | 210 | return nla_nest_end(skb, mx); |
| 187 | skb_trim(skb, (u8*)mx - skb->data); | 211 | |
| 188 | return -1; | 212 | nla_put_failure: |
| 213 | return nla_nest_cancel(skb, mx); | ||
| 189 | } | 214 | } |
| 190 | 215 | ||
| 191 | 216 | ||
| @@ -216,41 +241,73 @@ static void set_operstate(struct net_device *dev, unsigned char transition) · 24 unmodified lines | |||
| 216 | } | 241 | } |
| 217 | } | 242 | } |
| 218 | 243 | ||
| 219 | static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | 244 | static void copy_rtnl_link_stats(struct rtnl_link_stats *a, |
| 220 | int type, u32 pid, u32 seq, u32 change, | 245 | struct net_device_stats *b) |
| 221 | unsigned int flags) | ||
| 222 | { | 246 | { |
| 223 | struct ifinfomsg *r; | 247 | a->rx_packets = b->rx_packets; |
| 224 | struct nlmsghdr *nlh; | 248 | a->tx_packets = b->tx_packets; |
| 225 | unsigned char *b = skb->tail; | 249 | a->rx_bytes = b->rx_bytes; |
| 226 | 250 | a->tx_bytes = b->tx_bytes; | |
| 227 | nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags); | 251 | a->rx_errors = b->rx_errors; |
| 228 | r = NLMSG_DATA(nlh); | 252 | a->tx_errors = b->tx_errors; |
| 229 | r->ifi_family = AF_UNSPEC; | 253 | a->rx_dropped = b->rx_dropped; |
| 230 | r->__ifi_pad = 0; | 254 | a->tx_dropped = b->tx_dropped; |
| 231 | r->ifi_type = dev->type; | 255 | |
| 232 | r->ifi_index = dev->ifindex; | 256 | a->multicast = b->multicast; |
| 233 | r->ifi_flags = dev_get_flags(dev); | 257 | a->collisions = b->collisions; |
| 234 | r->ifi_change = change; | 258 | |
| 235 | 259 | a->rx_length_errors = b->rx_length_errors; | |
| 236 | RTA_PUT(skb, IFLA_IFNAME, strlen(dev->name)+1, dev->name); | 260 | a->rx_over_errors = b->rx_over_errors; |
| 237 | 261 | a->rx_crc_errors = b->rx_crc_errors; | |
| 238 | if (1) { | 262 | a->rx_frame_errors = b->rx_frame_errors; |
| 239 | u32 txqlen = dev->tx_queue_len; | 263 | a->rx_fifo_errors = b->rx_fifo_errors; |
| 240 | RTA_PUT(skb, IFLA_TXQLEN, sizeof(txqlen), &txqlen); | 264 | a->rx_missed_errors = b->rx_missed_errors; |
| 241 | } | 265 | |
| 266 | a->tx_aborted_errors = b->tx_aborted_errors; | ||
| 267 | a->tx_carrier_errors = b->tx_carrier_errors; | ||
| 268 | a->tx_fifo_errors = b->tx_fifo_errors; | ||
| 269 | a->tx_heartbeat_errors = b->tx_heartbeat_errors; | ||
| 270 | a->tx_window_errors = b->tx_window_errors; | ||
| 271 | |||
| 272 | a->rx_compressed = b->rx_compressed; | ||
| 273 | a->tx_compressed = b->tx_compressed; | ||
| 274 | }; | ||
| 242 | 275 | ||
| 243 | if (1) { | 276 | static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, |
| 244 | u32 weight = dev->weight; | 277 | void *iwbuf, int iwbuflen, int type, u32 pid, |
| 245 | RTA_PUT(skb, IFLA_WEIGHT, sizeof(weight), &weight); | 278 | u32 seq, u32 change, unsigned int flags) |
| 246 | } | 279 | { |
| 280 | struct ifinfomsg *ifm; | ||
| 281 | struct nlmsghdr *nlh; | ||
| 282 | |||
| 283 | nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); | ||
| 284 | if (nlh == NULL) | ||
| 285 | return -ENOBUFS; | ||
| 286 | |||
| 287 | ifm = nlmsg_data(nlh); | ||
| 288 | ifm->ifi_family = AF_UNSPEC; | ||
| 289 | ifm->__ifi_pad = 0; | ||
| 290 | ifm->ifi_type = dev->type; | ||
| 291 | ifm->ifi_index = dev->ifindex; | ||
| 292 | ifm->ifi_flags = dev_get_flags(dev); | ||
| 293 | ifm->ifi_change = change; | ||
| 294 | |||
| 295 | NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name); | ||
| 296 | NLA_PUT_U32(skb, IFLA_TXQLEN, dev->tx_queue_len); | ||
| 297 | NLA_PUT_U32(skb, IFLA_WEIGHT, dev->weight); | ||
| 298 | NLA_PUT_U8(skb, IFLA_OPERSTATE, | ||
| 299 | netif_running(dev) ? dev->operstate : IF_OPER_DOWN); | ||
| 300 | NLA_PUT_U8(skb, IFLA_LINKMODE, dev->link_mode); | ||
| 301 | NLA_PUT_U32(skb, IFLA_MTU, dev->mtu); | ||
| 302 | |||
| 303 | if (dev->ifindex != dev->iflink) | ||
| 304 | NLA_PUT_U32(skb, IFLA_LINK, dev->iflink); | ||
| 305 | |||
| 306 | if (dev->master) | ||
| 307 | NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex); | ||
| 247 | 308 | ||
| 248 | if (1) { | 309 | if (dev->qdisc_sleeping) |
| 249 | u8 operstate = netif_running(dev)?dev->operstate:IF_OPER_DOWN; | 310 | NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc_sleeping->ops->id); |
| 250 | u8 link_mode = dev->link_mode; | ||
| 251 | RTA_PUT(skb, IFLA_OPERSTATE, sizeof(operstate), &operstate); | ||
| 252 | RTA_PUT(skb, IFLA_LINKMODE, sizeof(link_mode), &link_mode); | ||
| 253 | } | ||
| 254 | 311 | ||
| 255 | if (1) { | 312 | if (1) { |
| 256 | struct rtnl_link_ifmap map = { | 313 | struct rtnl_link_ifmap map = { |
| @@ -261,58 +318,38 @@ static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, · 4 unmodified lines | |||
| 261 | .dma = dev->dma, | 318 | .dma = dev->dma, |
| 262 | .port = dev->if_port, | 319 | .port = dev->if_port, |
| 263 | }; | 320 | }; |
| 264 | RTA_PUT(skb, IFLA_MAP, sizeof(map), &map); | 321 | NLA_PUT(skb, IFLA_MAP, sizeof(map), &map); |
| 265 | } | 322 | } |
| 266 | 323 | ||
| 267 | if (dev->addr_len) { | 324 | if (dev->addr_len) { |
| 268 | RTA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr); | 325 | NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr); |
| 269 | RTA_PUT(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast); | 326 | NLA_PUT(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast); |
| 270 | } | ||
| 271 | |||
| 272 | if (1) { | ||
| 273 | u32 mtu = dev->mtu; | ||
| 274 | RTA_PUT(skb, IFLA_MTU, sizeof(mtu), &mtu); | ||
| 275 | } | ||
| 276 | |||
| 277 | if (dev->ifindex != dev->iflink) { | ||
| 278 | u32 iflink = dev->iflink; | ||
| 279 | RTA_PUT(skb, IFLA_LINK, sizeof(iflink), &iflink); | ||
| 280 | } | ||
| 281 | |||
| 282 | if (dev->qdisc_sleeping) | ||
| 283 | RTA_PUT(skb, IFLA_QDISC, | ||
| 284 | strlen(dev->qdisc_sleeping->ops->id) + 1, | ||
| 285 | dev->qdisc_sleeping->ops->id); | ||
| 286 | |||
| 287 | if (dev->master) { | ||
| 288 | u32 master = dev->master->ifindex; | ||
| 289 | RTA_PUT(skb, IFLA_MASTER, sizeof(master), &master); | ||
| 290 | } | 327 | } |
| 291 | 328 | ||
| 292 | if (dev->get_stats) { | 329 | if (dev->get_stats) { |
| 293 | unsigned long *stats = (unsigned long*)dev->get_stats(dev); | 330 | struct net_device_stats *stats = dev->get_stats(dev); |
| 294 | if (stats) { | 331 | if (stats) { |
| 295 | struct rtattr *a; | 332 | struct nlattr *attr; |
| 296 | __u32 *s; | 333 | |
| 297 | int i; | 334 | attr = nla_reserve(skb, IFLA_STATS, |
| 298 | int n = sizeof(struct rtnl_link_stats)/4; | 335 | sizeof(struct rtnl_link_stats)); |
| 299 | 336 | if (attr == NULL) | |
| 300 | a = __RTA_PUT(skb, IFLA_STATS, n*4); | 337 | goto nla_put_failure; |
| 301 | s = RTA_DATA(a); | 338 | |
| 302 | for (i=0; i<n; i++) | 339 | copy_rtnl_link_stats(nla_data(attr), stats); |
| 303 | s[i] = stats[i]; | ||
| 304 | } | 340 | } |
| 305 | } | 341 | } |
| 306 | nlh->nlmsg_len = skb->tail - b; | ||
| 307 | return skb->len; | ||
| 308 | 342 | ||
| 309 | nlmsg_failure: | 343 | if (iwbuf) |
| 310 | rtattr_failure: | 344 | NLA_PUT(skb, IFLA_WIRELESS, iwbuflen, iwbuf); |
| 311 | skb_trim(skb, b - skb->data); | 345 | |
| 312 | return -1; | 346 | return nlmsg_end(skb, nlh); |
| 347 | |||
| 348 | nla_put_failure: | ||
| 349 | return nlmsg_cancel(skb, nlh); | ||
| 313 | } | 350 | } |
| 314 | 351 | ||
| 315 | static int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | 352 | static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) |
| 316 | { | 353 | { |
| 317 | int idx; | 354 | int idx; |
| 318 | int s_idx = cb->args[0]; | 355 | int s_idx = cb->args[0]; |
| @@ -322,10 +359,9 @@ static int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *c · 3 unmodified lines | |||
| 322 | for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { | 359 | for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { |
| 323 | if (idx < s_idx) | 360 | if (idx < s_idx) |
| 324 | continue; | 361 | continue; |
| 325 | if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK, | 362 | if (rtnl_fill_ifinfo(skb, dev, NULL, 0, RTM_NEWLINK, |
| 326 | NETLINK_CB(cb->skb).pid, | 363 | NETLINK_CB(cb->skb).pid, |
| 327 | cb->nlh->nlmsg_seq, 0, | 364 | cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0) |
| 328 | NLM_F_MULTI) <= 0) | ||
| 329 | break; | 365 | break; |
| 330 | } | 366 | } |
| 331 | read_unlock(&dev_base_lock); | 367 | read_unlock(&dev_base_lock); |
| @@ -334,52 +370,70 @@ static int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *c · 2 unmodified lines | |||
| 334 | return skb->len; | 370 | return skb->len; |
| 335 | } | 371 | } |
| 336 | 372 | ||
| 337 | static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 373 | static struct nla_policy ifla_policy[IFLA_MAX+1] __read_mostly = { |
| 374 | [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 }, | ||
| 375 | [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, | ||
| 376 | [IFLA_MTU] = { .type = NLA_U32 }, | ||
| 377 | [IFLA_TXQLEN] = { .type = NLA_U32 }, | ||
| 378 | [IFLA_WEIGHT] = { .type = NLA_U32 }, | ||
| 379 | [IFLA_OPERSTATE] = { .type = NLA_U8 }, | ||
| 380 | [IFLA_LINKMODE] = { .type = NLA_U8 }, | ||
| 381 | }; | ||
| 382 | |||
| 383 | static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | ||
| 338 | { | 384 | { |
| 339 | struct ifinfomsg *ifm = NLMSG_DATA(nlh); | 385 | struct ifinfomsg *ifm; |
| 340 | struct rtattr **ida = arg; | ||
| 341 | struct net_device *dev; | 386 | struct net_device *dev; |
| 342 | int err, send_addr_notify = 0; | 387 | int err, send_addr_notify = 0, modified = 0; |
| 388 | struct nlattr *tb[IFLA_MAX+1]; | ||
| 389 | char ifname[IFNAMSIZ]; | ||
| 390 | |||
| 391 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); | ||
| 392 | if (err < 0) | ||
| 393 | goto errout; | ||
| 394 | |||
| 395 | if (tb[IFLA_IFNAME]) | ||
| 396 | nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); | ||
| 397 | else | ||
| 398 | ifname[0] = '\0'; | ||
| 343 | 399 | ||
| 400 | err = -EINVAL; | ||
| 401 | ifm = nlmsg_data(nlh); | ||
| 344 | if (ifm->ifi_index >= 0) | 402 | if (ifm->ifi_index >= 0) |
| 345 | dev = dev_get_by_index(ifm->ifi_index); | 403 | dev = dev_get_by_index(ifm->ifi_index); |
| 346 | else if (ida[IFLA_IFNAME - 1]) { | 404 | else if (tb[IFLA_IFNAME]) |
| 347 | char ifname[IFNAMSIZ]; | ||
| 348 | |||
| 349 | if (rtattr_strlcpy(ifname, ida[IFLA_IFNAME - 1], | ||
| 350 | IFNAMSIZ) >= IFNAMSIZ) | ||
| 351 | return -EINVAL; | ||
| 352 | dev = dev_get_by_name(ifname); | 405 | dev = dev_get_by_name(ifname); |
| 353 | } else | 406 | else |
| 354 | return -EINVAL; | 407 | goto errout; |
| 355 | 408 | ||
| 356 | if (!dev) | 409 | if (dev == NULL) { |
| 357 | return -ENODEV; | 410 | err = -ENODEV; |
| 411 | goto errout; | ||
| 412 | } | ||
| 358 | 413 | ||
| 359 | err = -EINVAL; | 414 | if (tb[IFLA_ADDRESS] && |
| 415 | nla_len(tb[IFLA_ADDRESS]) < dev->addr_len) | ||
| 416 | goto errout_dev; | ||
| 360 | 417 | ||
| 361 | if (ifm->ifi_flags) | 418 | if (tb[IFLA_BROADCAST] && |
| 362 | dev_change_flags(dev, ifm->ifi_flags); | 419 | nla_len(tb[IFLA_BROADCAST]) < dev->addr_len) |
| 420 | goto errout_dev; | ||
| 363 | 421 | ||
| 364 | if (ida[IFLA_MAP - 1]) { | 422 | if (tb[IFLA_MAP]) { |
| 365 | struct rtnl_link_ifmap *u_map; | 423 | struct rtnl_link_ifmap *u_map; |
| 366 | struct ifmap k_map; | 424 | struct ifmap k_map; |
| 367 | 425 | ||
| 368 | if (!dev->set_config) { | 426 | if (!dev->set_config) { |
| 369 | err = -EOPNOTSUPP; | 427 | err = -EOPNOTSUPP; |
| 370 | goto out; | 428 | goto errout_dev; |
| 371 | } | 429 | } |
| 372 | 430 | ||
| 373 | if (!netif_device_present(dev)) { | 431 | if (!netif_device_present(dev)) { |
| 374 | err = -ENODEV; | 432 | err = -ENODEV; |
| 375 | goto out; | 433 | goto errout_dev; |
| 376 | } | 434 | } |
| 377 | |||
| 378 | if (ida[IFLA_MAP - 1]->rta_len != RTA_LENGTH(sizeof(*u_map))) | ||
| 379 | goto out; | ||
| 380 | |||
| 381 | u_map = RTA_DATA(ida[IFLA_MAP - 1]); | ||
| 382 | 435 | ||
| 436 | u_map = nla_data(tb[IFLA_MAP]); | ||
| 383 | k_map.mem_start = (unsigned long) u_map->mem_start; | 437 | k_map.mem_start = (unsigned long) u_map->mem_start; |
| 384 | k_map.mem_end = (unsigned long) u_map->mem_end; | 438 | k_map.mem_end = (unsigned long) u_map->mem_end; |
| 385 | k_map.base_addr = (unsigned short) u_map->base_addr; | 439 | k_map.base_addr = (unsigned short) u_map->base_addr; |
| @@ -388,200 +442,175 @@ static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) · 2 unmodified lines | |||
| 388 | k_map.port = (unsigned char) u_map->port; | 442 | k_map.port = (unsigned char) u_map->port; |
| 389 | 443 | ||
| 390 | err = dev->set_config(dev, &k_map); | 444 | err = dev->set_config(dev, &k_map); |
| 445 | if (err < 0) | ||
| 446 | goto errout_dev; | ||
| 391 | 447 | ||
| 392 | if (err) | 448 | modified = 1; |
| 393 | goto out; | ||
| 394 | } | 449 | } |
| 395 | 450 | ||
| 396 | if (ida[IFLA_ADDRESS - 1]) { | 451 | if (tb[IFLA_ADDRESS]) { |
| 397 | struct sockaddr *sa; | 452 | struct sockaddr *sa; |
| 398 | int len; | 453 | int len; |
| 399 | 454 | ||
| 400 | if (!dev->set_mac_address) { | 455 | if (!dev->set_mac_address) { |
| 401 | err = -EOPNOTSUPP; | 456 | err = -EOPNOTSUPP; |
| 402 | goto out; | 457 | goto errout_dev; |
| 403 | } | 458 | } |
| 459 | |||
| 404 | if (!netif_device_present(dev)) { | 460 | if (!netif_device_present(dev)) { |
| 405 | err = -ENODEV; | 461 | err = -ENODEV; |
| 406 | goto out; | 462 | goto errout_dev; |
| 407 | } | 463 | } |
| 408 | if (ida[IFLA_ADDRESS - 1]->rta_len != RTA_LENGTH(dev->addr_len)) | ||
| 409 | goto out; | ||
| 410 | 464 | ||
| 411 | len = sizeof(sa_family_t) + dev->addr_len; | 465 | len = sizeof(sa_family_t) + dev->addr_len; |
| 412 | sa = kmalloc(len, GFP_KERNEL); | 466 | sa = kmalloc(len, GFP_KERNEL); |
| 413 | if (!sa) { | 467 | if (!sa) { |
| 414 | err = -ENOMEM; | 468 | err = -ENOMEM; |
| 415 | goto out; | 469 | goto errout_dev; |
| 416 | } | 470 | } |
| 417 | sa->sa_family = dev->type; | 471 | sa->sa_family = dev->type; |
| 418 | memcpy(sa->sa_data, RTA_DATA(ida[IFLA_ADDRESS - 1]), | 472 | memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]), |
| 419 | dev->addr_len); | 473 | dev->addr_len); |
| 420 | err = dev->set_mac_address(dev, sa); | 474 | err = dev->set_mac_address(dev, sa); |
| 421 | kfree(sa); | 475 | kfree(sa); |
| 422 | if (err) | 476 | if (err) |
| 423 | goto out; | 477 | goto errout_dev; |
| 424 | send_addr_notify = 1; | 478 | send_addr_notify = 1; |
| 479 | modified = 1; | ||
| 425 | } | 480 | } |
| 426 | 481 | ||
| 427 | if (ida[IFLA_BROADCAST - 1]) { | 482 | if (tb[IFLA_MTU]) { |
| 428 | if (ida[IFLA_BROADCAST - 1]->rta_len != RTA_LENGTH(dev->addr_len)) | 483 | err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU])); |
| 429 | goto out; | 484 | if (err < 0) |
| 430 | memcpy(dev->broadcast, RTA_DATA(ida[IFLA_BROADCAST - 1]), | 485 | goto errout_dev; |
| 431 | dev->addr_len); | 486 | modified = 1; |
| 432 | send_addr_notify = 1; | ||
| 433 | } | 487 | } |
| 434 | 488 | ||
| 435 | if (ida[IFLA_MTU - 1]) { | 489 | /* |
| 436 | if (ida[IFLA_MTU - 1]->rta_len != RTA_LENGTH(sizeof(u32))) | 490 | * Interface selected by interface index but interface |
| 437 | goto out; | 491 | * name provided implies that a name change has been |
| 438 | err = dev_set_mtu(dev, *((u32 *) RTA_DATA(ida[IFLA_MTU - 1]))); | 492 | * requested. |
| 439 | 493 | */ | |
| 440 | if (err) | 494 | if (ifm->ifi_index >= 0 && ifname[0]) { |
| 441 | goto out; | 495 | err = dev_change_name(dev, ifname); |
| 442 | 496 | if (err < 0) | |
| 497 | goto errout_dev; | ||
| 498 | modified = 1; | ||
| 443 | } | 499 | } |
| 444 | 500 | ||
| 445 | if (ida[IFLA_TXQLEN - 1]) { | 501 | #ifdef CONFIG_NET_WIRELESS_RTNETLINK |
| 446 | if (ida[IFLA_TXQLEN - 1]->rta_len != RTA_LENGTH(sizeof(u32))) | 502 | if (tb[IFLA_WIRELESS]) { |
| 447 | goto out; | 503 | /* Call Wireless Extensions. |
| 504 | * Various stuff checked in there... */ | ||
| 505 | err = wireless_rtnetlink_set(dev, nla_data(tb[IFLA_WIRELESS]), | ||
| 506 | nla_len(tb[IFLA_WIRELESS])); | ||
| 507 | if (err < 0) | ||
| 508 | goto errout_dev; | ||
| 509 | } | ||
| 510 | #endif /* CONFIG_NET_WIRELESS_RTNETLINK */ | ||
| 448 | 511 | ||
| 449 | dev->tx_queue_len = *((u32 *) RTA_DATA(ida[IFLA_TXQLEN - 1])); | 512 | if (tb[IFLA_BROADCAST]) { |
| 513 | nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len); | ||
| 514 | send_addr_notify = 1; | ||
| 450 | } | 515 | } |
| 451 | 516 | ||
| 452 | if (ida[IFLA_WEIGHT - 1]) { | ||
| 453 | if (ida[IFLA_WEIGHT - 1]->rta_len != RTA_LENGTH(sizeof(u32))) | ||
| 454 | goto out; | ||
| 455 | 517 | ||
| 456 | dev->weight = *((u32 *) RTA_DATA(ida[IFLA_WEIGHT - 1])); | 518 | if (ifm->ifi_flags) |
| 457 | } | 519 | dev_change_flags(dev, ifm->ifi_flags); |
| 458 | 520 | ||
| 459 | if (ida[IFLA_OPERSTATE - 1]) { | 521 | if (tb[IFLA_TXQLEN]) |
| 460 | if (ida[IFLA_OPERSTATE - 1]->rta_len != RTA_LENGTH(sizeof(u8))) | 522 | dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); |
| 461 | goto out; | ||
| 462 | 523 | ||
| 463 | set_operstate(dev, *((u8 *) RTA_DATA(ida[IFLA_OPERSTATE - 1]))); | 524 | if (tb[IFLA_WEIGHT]) |
| 464 | } | 525 | dev->weight = nla_get_u32(tb[IFLA_WEIGHT]); |
| 465 | 526 | ||
| 466 | if (ida[IFLA_LINKMODE - 1]) { | 527 | if (tb[IFLA_OPERSTATE]) |
| 467 | if (ida[IFLA_LINKMODE - 1]->rta_len != RTA_LENGTH(sizeof(u8))) | 528 | set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); |
| 468 | goto out; | ||
| 469 | 529 | ||
| 530 | if (tb[IFLA_LINKMODE]) { | ||
| 470 | write_lock_bh(&dev_base_lock); | 531 | write_lock_bh(&dev_base_lock); |
| 471 | dev->link_mode = *((u8 *) RTA_DATA(ida[IFLA_LINKMODE - 1])); | 532 | dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); |
| 472 | write_unlock_bh(&dev_base_lock); | 533 | write_unlock_bh(&dev_base_lock); |
| 473 | } | 534 | } |
| 474 | 535 | ||
| 475 | if (ifm->ifi_index >= 0 && ida[IFLA_IFNAME - 1]) { | ||
| 476 | char ifname[IFNAMSIZ]; | ||
| 477 | |||
| 478 | if (rtattr_strlcpy(ifname, ida[IFLA_IFNAME - 1], | ||
| 479 | IFNAMSIZ) >= IFNAMSIZ) | ||
| 480 | goto out; | ||
| 481 | err = dev_change_name(dev, ifname); | ||
| 482 | if (err) | ||
| 483 | goto out; | ||
| 484 | } | ||
| 485 | |||
| 486 | #ifdef CONFIG_NET_WIRELESS_RTNETLINK | ||
| 487 | if (ida[IFLA_WIRELESS - 1]) { | ||
| 488 | |||
| 489 | /* Call Wireless Extensions. | ||
| 490 | * Various stuff checked in there... */ | ||
| 491 | err = wireless_rtnetlink_set(dev, RTA_DATA(ida[IFLA_WIRELESS - 1]), ida[IFLA_WIRELESS - 1]->rta_len); | ||
| 492 | if (err) | ||
| 493 | goto out; | ||
| 494 | } | ||
| 495 | #endif /* CONFIG_NET_WIRELESS_RTNETLINK */ | ||
| 496 | |||
| 497 | err = 0; | 536 | err = 0; |
| 498 | 537 | ||
| 499 | out: | 538 | errout_dev: |
| 539 | if (err < 0 && modified && net_ratelimit()) | ||
| 540 | printk(KERN_WARNING "A link change request failed with " | ||
| 541 | "some changes comitted already. Interface %s may " | ||
| 542 | "have been left with an inconsistent configuration, " | ||
| 543 | "please check.\n", dev->name); | ||
| 544 | |||
| 500 | if (send_addr_notify) | 545 | if (send_addr_notify) |
| 501 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 546 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
| 502 | 547 | ||
| 503 | dev_put(dev); | 548 | dev_put(dev); |
| 549 | errout: | ||
| 504 | return err; | 550 | return err; |
| 505 | } | 551 | } |
| 506 | 552 | ||
| 507 | #ifdef CONFIG_NET_WIRELESS_RTNETLINK | 553 | static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) |
| 508 | static int do_getlink(struct sk_buff *in_skb, struct nlmsghdr* in_nlh, void *arg) | ||
| 509 | { | 554 | { |
| 510 | struct ifinfomsg *ifm = NLMSG_DATA(in_nlh); | 555 | struct ifinfomsg *ifm; |
| 511 | struct rtattr **ida = arg; | 556 | struct nlattr *tb[IFLA_MAX+1]; |
| 512 | struct net_device *dev; | 557 | struct net_device *dev = NULL; |
| 513 | struct ifinfomsg *r; | 558 | struct sk_buff *nskb; |
| 514 | struct nlmsghdr *nlh; | 559 | char *iw_buf = NULL, *iw = NULL; |
| 515 | int err = -ENOBUFS; | ||
| 516 | struct sk_buff *skb; | ||
| 517 | unsigned char *b; | ||
| 518 | char *iw_buf = NULL; | ||
| 519 | int iw_buf_len = 0; | 560 | int iw_buf_len = 0; |
| 561 | int err, payload; | ||
| 520 | 562 | ||
| 521 | if (ifm->ifi_index >= 0) | 563 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); |
| 564 | if (err < 0) | ||
| 565 | goto errout; | ||
| 566 | |||
| 567 | ifm = nlmsg_data(nlh); | ||
| 568 | if (ifm->ifi_index >= 0) { | ||
| 522 | dev = dev_get_by_index(ifm->ifi_index); | 569 | dev = dev_get_by_index(ifm->ifi_index); |
| 523 | else | 570 | if (dev == NULL) |
| 571 | return -ENODEV; | ||
| 572 | } else | ||
| 524 | return -EINVAL; | 573 | return -EINVAL; |
| 525 | if (!dev) | ||
| 526 | return -ENODEV; | ||
| 527 | 574 | ||
| 528 | #ifdef CONFIG_NET_WIRELESS_RTNETLINK | ||
| 529 | if (ida[IFLA_WIRELESS - 1]) { | ||
| 530 | 575 | ||
| 576 | #ifdef CONFIG_NET_WIRELESS_RTNETLINK | ||
| 577 | if (tb[IFLA_WIRELESS]) { | ||
| 531 | /* Call Wireless Extensions. We need to know the size before | 578 | /* Call Wireless Extensions. We need to know the size before |
| 532 | * we can alloc. Various stuff checked in there... */ | 579 | * we can alloc. Various stuff checked in there... */ |
| 533 | err = wireless_rtnetlink_get(dev, RTA_DATA(ida[IFLA_WIRELESS - 1]), ida[IFLA_WIRELESS - 1]->rta_len, &iw_buf, &iw_buf_len); | 580 | err = wireless_rtnetlink_get(dev, nla_data(tb[IFLA_WIRELESS]), |
| 534 | if (err) | 581 | nla_len(tb[IFLA_WIRELESS]), |
| 535 | goto out; | 582 | &iw_buf, &iw_buf_len); |
| 583 | if (err < 0) | ||
| 584 | goto errout; | ||
| 585 | |||
| 586 | iw += IW_EV_POINT_OFF; | ||
| 536 | } | 587 | } |
| 537 | #endif /* CONFIG_NET_WIRELESS_RTNETLINK */ | 588 | #endif /* CONFIG_NET_WIRELESS_RTNETLINK */ |
| 538 | 589 | ||
| 539 | /* Create a skb big enough to include all the data. | 590 | payload = NLMSG_ALIGN(sizeof(struct ifinfomsg) + |
| 540 | * Some requests are way bigger than 4k... Jean II */ | 591 | nla_total_size(iw_buf_len)); |
| 541 | skb = alloc_skb((NLMSG_LENGTH(sizeof(*r))) + (RTA_SPACE(iw_buf_len)), | 592 | nskb = nlmsg_new(nlmsg_total_size(payload), GFP_KERNEL); |
| 542 | GFP_KERNEL); | 593 | if (nskb == NULL) { |
| 543 | if (!skb) | 594 | err = -ENOBUFS; |
| 544 | goto out; | 595 | goto errout; |
| 545 | b = skb->tail; | 596 | } |
| 546 | 597 | ||
| 547 | /* Put in the message the usual good stuff */ | 598 | err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK, |
| 548 | nlh = NLMSG_PUT(skb, NETLINK_CB(in_skb).pid, in_nlh->nlmsg_seq, | 599 | NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0); |
| 549 | RTM_NEWLINK, sizeof(*r)); | 600 | if (err <= 0) { |
| 550 | r = NLMSG_DATA(nlh); | 601 | kfree_skb(nskb); |
| 551 | r->ifi_family = AF_UNSPEC; | 602 | goto errout; |
| 552 | r->__ifi_pad = 0; | 603 | } |
| 553 | r->ifi_type = dev->type; | 604 | |
| 554 | r->ifi_index = dev->ifindex; | 605 | err = rtnl_unicast(skb, NETLINK_CB(skb).pid); |
| 555 | r->ifi_flags = dev->flags; | 606 | errout: |
| 556 | r->ifi_change = 0; | 607 | kfree(iw_buf); |
| 557 | |||
| 558 | /* Put the wireless payload if it exist */ | ||
| 559 | if(iw_buf != NULL) | ||
| 560 | RTA_PUT(skb, IFLA_WIRELESS, iw_buf_len, | ||
| 561 | iw_buf + IW_EV_POINT_OFF); | ||
| 562 | |||
| 563 | nlh->nlmsg_len = skb->tail - b; | ||
| 564 | |||
| 565 | /* Needed ? */ | ||
| 566 | NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid; | ||
| 567 | |||
| 568 | err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); | ||
| 569 | if (err > 0) | ||
| 570 | err = 0; | ||
| 571 | out: | ||
| 572 | if(iw_buf != NULL) | ||
| 573 | kfree(iw_buf); | ||
| 574 | dev_put(dev); | 608 | dev_put(dev); |
| 575 | return err; | ||
| 576 | 609 | ||
| 577 | rtattr_failure: | 610 | return err; |
| 578 | nlmsg_failure: | ||
| 579 | kfree_skb(skb); | ||
| 580 | goto out; | ||
| 581 | } | 611 | } |
| 582 | #endif /* CONFIG_NET_WIRELESS_RTNETLINK */ | ||
| 583 | 612 | ||
| 584 | static int rtnetlink_dump_all(struct sk_buff *skb, struct netlink_callback *cb) | 613 | static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) |
| 585 | { | 614 | { |
| 586 | int idx; | 615 | int idx; |
| 587 | int s_idx = cb->family; | 616 | int s_idx = cb->family; |
| @@ -608,20 +637,22 @@ static int rtnetlink_dump_all(struct sk_buff *skb, struct netlink_callback *cb) · 20 unmodified lines | |||
| 608 | void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) | 637 | void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) |
| 609 | { | 638 | { |
| 610 | struct sk_buff *skb; | 639 | struct sk_buff *skb; |
| 611 | int size = NLMSG_SPACE(sizeof(struct ifinfomsg) + | 640 | int err = -ENOBUFS; |
| 612 | sizeof(struct rtnl_link_ifmap) + | ||
| 613 | sizeof(struct rtnl_link_stats) + 128); | ||
| 614 | 641 | ||
| 615 | skb = alloc_skb(size, GFP_KERNEL); | 642 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); |
| 616 | if (!skb) | 643 | if (skb == NULL) |
| 617 | return; | 644 | goto errout; |
| 618 | 645 | ||
| 619 | if (rtnetlink_fill_ifinfo(skb, dev, type, 0, 0, change, 0) < 0) { | 646 | err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0); |
| 647 | if (err < 0) { | ||
| 620 | kfree_skb(skb); | 648 | kfree_skb(skb); |
| 621 | return; | 649 | goto errout; |
| 622 | } | 650 | } |
| 623 | NETLINK_CB(skb).dst_group = RTNLGRP_LINK; | 651 | |
| 624 | netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_KERNEL); | 652 | err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL); |
| 653 | errout: | ||
| 654 | if (err < 0) | ||
| 655 | rtnl_set_sk_err(RTNLGRP_LINK, err); | ||
| 625 | } | 656 | } |
| 626 | 657 | ||
| 627 | /* Protected by RTNL sempahore. */ | 658 | /* Protected by RTNL sempahore. */ |
| @@ -746,18 +777,19 @@ static void rtnetlink_rcv(struct sock *sk, int len) · 118 unmodified lines | |||
| 746 | 777 | ||
| 747 | static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = | 778 | static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = |
| 748 | { | 779 | { |
| 749 | [RTM_GETLINK - RTM_BASE] = { | 780 | [RTM_GETLINK - RTM_BASE] = { .doit = rtnl_getlink, |
| 750 | #ifdef CONFIG_NET_WIRELESS_RTNETLINK | 781 | .dumpit = rtnl_dump_ifinfo }, |
| 751 | .doit = do_getlink, | 782 | [RTM_SETLINK - RTM_BASE] = { .doit = rtnl_setlink }, |
| 752 | #endif /* CONFIG_NET_WIRELESS_RTNETLINK */ | 783 | [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnl_dump_all }, |
| 753 | .dumpit = rtnetlink_dump_ifinfo }, | 784 | [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnl_dump_all }, |
| 754 | [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, | ||
| 755 | [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, | ||
| 756 | [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, | ||
| 757 | [RTM_NEWNEIGH - RTM_BASE] = { .doit = neigh_add }, | 785 | [RTM_NEWNEIGH - RTM_BASE] = { .doit = neigh_add }, |
| 758 | [RTM_DELNEIGH - RTM_BASE] = { .doit = neigh_delete }, | 786 | [RTM_DELNEIGH - RTM_BASE] = { .doit = neigh_delete }, |
| 759 | [RTM_GETNEIGH - RTM_BASE] = { .dumpit = neigh_dump_info }, | 787 | [RTM_GETNEIGH - RTM_BASE] = { .dumpit = neigh_dump_info }, |
| 760 | [RTM_GETRULE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, | 788 | #ifdef CONFIG_FIB_RULES |
| 789 | [RTM_NEWRULE - RTM_BASE] = { .doit = fib_nl_newrule }, | ||
| 790 | [RTM_DELRULE - RTM_BASE] = { .doit = fib_nl_delrule }, | ||
| 791 | #endif | ||
| 792 | [RTM_GETRULE - RTM_BASE] = { .dumpit = rtnl_dump_all }, | ||
| 761 | [RTM_GETNEIGHTBL - RTM_BASE] = { .dumpit = neightbl_dump_info }, | 793 | [RTM_GETNEIGHTBL - RTM_BASE] = { .dumpit = neightbl_dump_info }, |
| 762 | [RTM_SETNEIGHTBL - RTM_BASE] = { .doit = neightbl_set }, | 794 | [RTM_SETNEIGHTBL - RTM_BASE] = { .doit = neightbl_set }, |
| 763 | }; | 795 | }; |
| @@ -817,7 +849,9 @@ EXPORT_SYMBOL(rtattr_strlcpy); · 53 unmodified lines | |||
| 817 | EXPORT_SYMBOL(rtattr_parse); | 849 | EXPORT_SYMBOL(rtattr_parse); |
| 818 | EXPORT_SYMBOL(rtnetlink_links); | 850 | EXPORT_SYMBOL(rtnetlink_links); |
| 819 | EXPORT_SYMBOL(rtnetlink_put_metrics); | 851 | EXPORT_SYMBOL(rtnetlink_put_metrics); |
| 820 | EXPORT_SYMBOL(rtnl); | ||
| 821 | EXPORT_SYMBOL(rtnl_lock); | 852 | EXPORT_SYMBOL(rtnl_lock); |
| 822 | EXPORT_SYMBOL(rtnl_trylock); | 853 | EXPORT_SYMBOL(rtnl_trylock); |
| 823 | EXPORT_SYMBOL(rtnl_unlock); | 854 | EXPORT_SYMBOL(rtnl_unlock); |
| 855 | EXPORT_SYMBOL(rtnl_unicast); | ||
| 856 | EXPORT_SYMBOL(rtnl_notify); | ||
| 857 | EXPORT_SYMBOL(rtnl_set_sk_err); | ||
| @@ -1397,7 +1397,7 @@ void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to) · 1396 unmodified lines | |||
| 1397 | unsigned int csum; | 1397 | unsigned int csum; |
| 1398 | long csstart; | 1398 | long csstart; |
| 1399 | 1399 | ||
| 1400 | if (skb->ip_summed == CHECKSUM_HW) | 1400 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
| 1401 | csstart = skb->h.raw - skb->data; | 1401 | csstart = skb->h.raw - skb->data; |
| 1402 | else | 1402 | else |
| 1403 | csstart = skb_headlen(skb); | 1403 | csstart = skb_headlen(skb); |
| @@ -1411,7 +1411,7 @@ void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to) · 7 unmodified lines | |||
| 1411 | csum = skb_copy_and_csum_bits(skb, csstart, to + csstart, | 1411 | csum = skb_copy_and_csum_bits(skb, csstart, to + csstart, |
| 1412 | skb->len - csstart, 0); | 1412 | skb->len - csstart, 0); |
| 1413 | 1413 | ||
| 1414 | if (skb->ip_summed == CHECKSUM_HW) { | 1414 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1415 | long csstuff = csstart + skb->csum; | 1415 | long csstuff = csstart + skb->csum; |
| 1416 | 1416 | ||
| 1417 | *((unsigned short *)(to + csstuff)) = csum_fold(csum); | 1417 | *((unsigned short *)(to + csstuff)) = csum_fold(csum); |
| @@ -1898,10 +1898,10 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, · 480 unmodified lines | |||
| 1898 | * @len: length of data pulled | 1898 | * @len: length of data pulled |
| 1899 | * | 1899 | * |
| 1900 | * This function performs an skb_pull on the packet and updates | 1900 | * This function performs an skb_pull on the packet and updates |
| 1901 | * update the CHECKSUM_HW checksum. It should be used on receive | 1901 | * update the CHECKSUM_COMPLETE checksum. It should be used on |
| 1902 | * path processing instead of skb_pull unless you know that the | 1902 | * receive path processing instead of skb_pull unless you know |
| 1903 | * checksum difference is zero (e.g., a valid IP header) or you | 1903 | * that the checksum difference is zero (e.g., a valid IP header) |
| 1904 | * are setting ip_summed to CHECKSUM_NONE. | 1904 | * or you are setting ip_summed to CHECKSUM_NONE. |
| 1905 | */ | 1905 | */ |
| 1906 | unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len) | 1906 | unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len) |
| 1907 | { | 1907 | { |
| @@ -1994,7 +1994,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) · 86 unmodified lines | |||
| 1994 | frag = skb_shinfo(nskb)->frags; | 1994 | frag = skb_shinfo(nskb)->frags; |
| 1995 | k = 0; | 1995 | k = 0; |
| 1996 | 1996 | ||
| 1997 | nskb->ip_summed = CHECKSUM_HW; | 1997 | nskb->ip_summed = CHECKSUM_PARTIAL; |
| 1998 | nskb->csum = skb->csum; | 1998 | nskb->csum = skb->csum; |
| 1999 | memcpy(skb_put(nskb, hsize), skb->data + offset, hsize); | 1999 | memcpy(skb_put(nskb, hsize), skb->data + offset, hsize); |
| 2000 | 2000 | ||
| @@ -2046,19 +2046,14 @@ void __init skb_init(void) · 45 unmodified lines | |||
| 2046 | skbuff_head_cache = kmem_cache_create("skbuff_head_cache", | 2046 | skbuff_head_cache = kmem_cache_create("skbuff_head_cache", |
| 2047 | sizeof(struct sk_buff), | 2047 | sizeof(struct sk_buff), |
| 2048 | 0, | 2048 | 0, |
| 2049 | SLAB_HWCACHE_ALIGN, | 2049 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, |
| 2050 | NULL, NULL); | 2050 | NULL, NULL); |
| 2051 | if (!skbuff_head_cache) | ||
| 2052 | panic("cannot create skbuff cache"); | ||
| 2053 | |||
| 2054 | skbuff_fclone_cache = kmem_cache_create("skbuff_fclone_cache", | 2051 | skbuff_fclone_cache = kmem_cache_create("skbuff_fclone_cache", |
| 2055 | (2*sizeof(struct sk_buff)) + | 2052 | (2*sizeof(struct sk_buff)) + |
| 2056 | sizeof(atomic_t), | 2053 | sizeof(atomic_t), |
| 2057 | 0, | 2054 | 0, |
| 2058 | SLAB_HWCACHE_ALIGN, | 2055 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, |
| 2059 | NULL, NULL); | 2056 | NULL, NULL); |
| 2060 | if (!skbuff_fclone_cache) | ||
| 2061 | panic("cannot create skbuff cache"); | ||
| 2062 | } | 2057 | } |
| 2063 | 2058 | ||
| 2064 | EXPORT_SYMBOL(___pskb_trim); | 2059 | EXPORT_SYMBOL(___pskb_trim); |
| @@ -187,13 +187,13 @@ static struct lock_class_key af_callback_keys[AF_MAX]; · 186 unmodified lines | |||
| 187 | #define SK_RMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS) | 187 | #define SK_RMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS) |
| 188 | 188 | ||
| 189 | /* Run time adjustable parameters. */ | 189 | /* Run time adjustable parameters. */ |
| 190 | __u32 sysctl_wmem_max = SK_WMEM_MAX; | 190 | __u32 sysctl_wmem_max __read_mostly = SK_WMEM_MAX; |
| 191 | __u32 sysctl_rmem_max = SK_RMEM_MAX; | 191 | __u32 sysctl_rmem_max __read_mostly = SK_RMEM_MAX; |
| 192 | __u32 sysctl_wmem_default = SK_WMEM_MAX; | 192 | __u32 sysctl_wmem_default __read_mostly = SK_WMEM_MAX; |
| 193 | __u32 sysctl_rmem_default = SK_RMEM_MAX; | 193 | __u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX; |
| 194 | 194 | ||
| 195 | /* Maximal space eaten by iovec or ancilliary data plus some space */ | 195 | /* Maximal space eaten by iovec or ancilliary data plus some space */ |
| 196 | int sysctl_optmem_max = sizeof(unsigned long)*(2*UIO_MAXIOV + 512); | 196 | int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512); |
| 197 | 197 | ||
| 198 | static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) | 198 | static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) |
| 199 | { | 199 | { |
| @@ -247,11 +247,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) · 47 unmodified lines | |||
| 247 | goto out; | 247 | goto out; |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | /* It would be deadlock, if sock_queue_rcv_skb is used | 250 | err = sk_filter(sk, skb); |
| 251 | with socket lock! We assume that users of this | ||
| 252 | function are lock free. | ||
| 253 | */ | ||
| 254 | err = sk_filter(sk, skb, 1); | ||
| 255 | if (err) | 251 | if (err) |
| 256 | goto out; | 252 | goto out; |
| 257 | 253 | ||
| @@ -278,7 +274,7 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb) · 20 unmodified lines | |||
| 278 | { | 274 | { |
| 279 | int rc = NET_RX_SUCCESS; | 275 | int rc = NET_RX_SUCCESS; |
| 280 | 276 | ||
| 281 | if (sk_filter(sk, skb, 0)) | 277 | if (sk_filter(sk, skb)) |
| 282 | goto discard_and_relse; | 278 | goto discard_and_relse; |
| 283 | 279 | ||
| 284 | skb->dev = NULL; | 280 | skb->dev = NULL; |
| @@ -606,15 +602,15 @@ set_rcvbuf: · 321 unmodified lines | |||
| 606 | break; | 602 | break; |
| 607 | 603 | ||
| 608 | case SO_DETACH_FILTER: | 604 | case SO_DETACH_FILTER: |
| 609 | spin_lock_bh(&sk->sk_lock.slock); | 605 | rcu_read_lock_bh(); |
| 610 | filter = sk->sk_filter; | 606 | filter = rcu_dereference(sk->sk_filter); |
| 611 | if (filter) { | 607 | if (filter) { |
| 612 | sk->sk_filter = NULL; | 608 | rcu_assign_pointer(sk->sk_filter, NULL); |
| 613 | spin_unlock_bh(&sk->sk_lock.slock); | ||
| 614 | sk_filter_release(sk, filter); | 609 | sk_filter_release(sk, filter); |
| 610 | rcu_read_unlock_bh(); | ||
| 615 | break; | 611 | break; |
| 616 | } | 612 | } |
| 617 | spin_unlock_bh(&sk->sk_lock.slock); | 613 | rcu_read_unlock_bh(); |
| 618 | ret = -ENONET; | 614 | ret = -ENONET; |
| 619 | break; | 615 | break; |
| 620 | 616 | ||
| @@ -884,10 +880,10 @@ void sk_free(struct sock *sk) · 263 unmodified lines | |||
| 884 | if (sk->sk_destruct) | 880 | if (sk->sk_destruct) |
| 885 | sk->sk_destruct(sk); | 881 | sk->sk_destruct(sk); |
| 886 | 882 | ||
| 887 | filter = sk->sk_filter; | 883 | filter = rcu_dereference(sk->sk_filter); |
| 888 | if (filter) { | 884 | if (filter) { |
| 889 | sk_filter_release(sk, filter); | 885 | sk_filter_release(sk, filter); |
| 890 | sk->sk_filter = NULL; | 886 | rcu_assign_pointer(sk->sk_filter, NULL); |
| 891 | } | 887 | } |
| 892 | 888 | ||
| 893 | sock_disable_timestamp(sk); | 889 | sock_disable_timestamp(sk); |
| @@ -911,7 +907,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) · 17 unmodified lines | |||
| 911 | if (newsk != NULL) { | 907 | if (newsk != NULL) { |
| 912 | struct sk_filter *filter; | 908 | struct sk_filter *filter; |
| 913 | 909 | ||
| 914 | memcpy(newsk, sk, sk->sk_prot->obj_size); | 910 | sock_copy(newsk, sk); |
| 915 | 911 | ||
| 916 | /* SANITY */ | 912 | /* SANITY */ |
| 917 | sk_node_init(&newsk->sk_node); | 913 | sk_node_init(&newsk->sk_node); |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | * Authors: | 4 | * Authors: |
| 5 | * net_random Alan Cox | 5 | * net_random Alan Cox |
| 6 | * net_ratelimit Andy Kleen | 6 | * net_ratelimit Andy Kleen |
| 7 | * in{4,6}_pton YOSHIFUJI Hideaki, Copyright (C)2006 USAGI/WIDE Project | ||
| 7 | * | 8 | * |
| 8 | * Created by Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> | 9 | * Created by Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> |
| 9 | * | 10 | * |
| @@ -191,3 +192,215 @@ __be32 in_aton(const char *str) · 181 unmodified lines | |||
| 191 | } | 192 | } |
| 192 | 193 | ||
| 193 | EXPORT_SYMBOL(in_aton); | 194 | EXPORT_SYMBOL(in_aton); |
| 195 | |||
| 196 | #define IN6PTON_XDIGIT 0x00010000 | ||
| 197 | #define IN6PTON_DIGIT 0x00020000 | ||
| 198 | #define IN6PTON_COLON_MASK 0x00700000 | ||
| 199 | #define IN6PTON_COLON_1 0x00100000 /* single : requested */ | ||
| 200 | #define IN6PTON_COLON_2 0x00200000 /* second : requested */ | ||
| 201 | #define IN6PTON_COLON_1_2 0x00400000 /* :: requested */ | ||
| 202 | #define IN6PTON_DOT 0x00800000 /* . */ | ||
| 203 | #define IN6PTON_DELIM 0x10000000 | ||
| 204 | #define IN6PTON_NULL 0x20000000 /* first/tail */ | ||
| 205 | #define IN6PTON_UNKNOWN 0x40000000 | ||
| 206 | |||
| 207 | static inline int digit2bin(char c, char delim) | ||
| 208 | { | ||
| 209 | if (c == delim || c == '\0') | ||
| 210 | return IN6PTON_DELIM; | ||
| 211 | if (c == '.') | ||
| 212 | return IN6PTON_DOT; | ||
| 213 | if (c >= '0' && c <= '9') | ||
| 214 | return (IN6PTON_DIGIT | (c - '0')); | ||
| 215 | return IN6PTON_UNKNOWN; | ||
| 216 | } | ||
| 217 | |||
| 218 | static inline int xdigit2bin(char c, char delim) | ||
| 219 | { | ||
| 220 | if (c == delim || c == '\0') | ||
| 221 | return IN6PTON_DELIM; | ||
| 222 | if (c == ':') | ||
| 223 | return IN6PTON_COLON_MASK; | ||
| 224 | if (c == '.') | ||
| 225 | return IN6PTON_DOT; | ||
| 226 | if (c >= '0' && c <= '9') | ||
| 227 | return (IN6PTON_XDIGIT | IN6PTON_DIGIT| (c - '0')); | ||
| 228 | if (c >= 'a' && c <= 'f') | ||
| 229 | return (IN6PTON_XDIGIT | (c - 'a' + 10)); | ||
| 230 | if (c >= 'A' && c <= 'F') | ||
| 231 | return (IN6PTON_XDIGIT | (c - 'A' + 10)); | ||
| 232 | return IN6PTON_UNKNOWN; | ||
| 233 | } | ||
| 234 | |||
| 235 | int in4_pton(const char *src, int srclen, | ||
| 236 | u8 *dst, | ||
| 237 | char delim, const char **end) | ||
| 238 | { | ||
| 239 | const char *s; | ||
| 240 | u8 *d; | ||
| 241 | u8 dbuf[4]; | ||
| 242 | int ret = 0; | ||
| 243 | int i; | ||
| 244 | int w = 0; | ||
| 245 | |||
| 246 | if (srclen < 0) | ||
| 247 | srclen = strlen(src); | ||
| 248 | s = src; | ||
| 249 | d = dbuf; | ||
| 250 | i = 0; | ||
| 251 | while(1) { | ||
| 252 | int c; | ||
| 253 | c = xdigit2bin(srclen > 0 ? *s : '\0', delim); | ||
| 254 | if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM))) { | ||
| 255 | goto out; | ||
| 256 | } | ||
| 257 | if (c & (IN6PTON_DOT | IN6PTON_DELIM)) { | ||
| 258 | if (w == 0) | ||
| 259 | goto out; | ||
| 260 | *d++ = w & 0xff; | ||
| 261 | w = 0; | ||
| 262 | i++; | ||
| 263 | if (c & IN6PTON_DELIM) { | ||
| 264 | if (i != 4) | ||
| 265 | goto out; | ||
| 266 | break; | ||
| 267 | } | ||
| 268 | goto cont; | ||
| 269 | } | ||
| 270 | w = (w * 10) + c; | ||
| 271 | if ((w & 0xffff) > 255) { | ||
| 272 | goto out; | ||
| 273 | } | ||
| 274 | cont: | ||
| 275 | if (i >= 4) | ||
| 276 | goto out; | ||
| 277 | s++; | ||
| 278 | srclen--; | ||
| 279 | } | ||
| 280 | ret = 1; | ||
| 281 | memcpy(dst, dbuf, sizeof(dbuf)); | ||
| 282 | out: | ||
| 283 | if (end) | ||
| 284 | *end = s; | ||
| 285 | return ret; | ||
| 286 | } | ||
| 287 | |||
| 288 | EXPORT_SYMBOL(in4_pton); | ||
| 289 | |||
| 290 | int in6_pton(const char *src, int srclen, | ||
| 291 | u8 *dst, | ||
| 292 | char delim, const char **end) | ||
| 293 | { | ||
| 294 | const char *s, *tok = NULL; | ||
| 295 | u8 *d, *dc = NULL; | ||
| 296 | u8 dbuf[16]; | ||
| 297 | int ret = 0; | ||
| 298 | int i; | ||
| 299 | int state = IN6PTON_COLON_1_2 | IN6PTON_XDIGIT | IN6PTON_NULL; | ||
| 300 | int w = 0; | ||
| 301 | |||
| 302 | memset(dbuf, 0, sizeof(dbuf)); | ||
| 303 | |||
| 304 | s = src; | ||
| 305 | d = dbuf; | ||
| 306 | if (srclen < 0) | ||
| 307 | srclen = strlen(src); | ||
| 308 | |||
| 309 | while (1) { | ||
| 310 | int c; | ||
| 311 | |||
| 312 | c = xdigit2bin(srclen > 0 ? *s : '\0', delim); | ||
| 313 | if (!(c & state)) | ||
| 314 | goto out; | ||
| 315 | if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) { | ||
| 316 | /* process one 16-bit word */ | ||
| 317 | if (!(state & IN6PTON_NULL)) { | ||
| 318 | *d++ = (w >> 8) & 0xff; | ||
| 319 | *d++ = w & 0xff; | ||
| 320 | } | ||
| 321 | w = 0; | ||
| 322 | if (c & IN6PTON_DELIM) { | ||
| 323 | /* We've processed last word */ | ||
| 324 | break; | ||
| 325 | } | ||
| 326 | /* | ||
| 327 | * COLON_1 => XDIGIT | ||
| 328 | * COLON_2 => XDIGIT|DELIM | ||
| 329 | * COLON_1_2 => COLON_2 | ||
| 330 | */ | ||
| 331 | switch (state & IN6PTON_COLON_MASK) { | ||
| 332 | case IN6PTON_COLON_2: | ||
| 333 | dc = d; | ||
| 334 | state = IN6PTON_XDIGIT | IN6PTON_DELIM; | ||
| 335 | if (dc - dbuf >= sizeof(dbuf)) | ||
| 336 | state |= IN6PTON_NULL; | ||
| 337 | break; | ||
| 338 | case IN6PTON_COLON_1|IN6PTON_COLON_1_2: | ||
| 339 | state = IN6PTON_XDIGIT | IN6PTON_COLON_2; | ||
| 340 | break; | ||
| 341 | case IN6PTON_COLON_1: | ||
| 342 | state = IN6PTON_XDIGIT; | ||
| 343 | break; | ||
| 344 | case IN6PTON_COLON_1_2: | ||
| 345 | state = IN6PTON_COLON_2; | ||
| 346 | break; | ||
| 347 | default: | ||
| 348 | state = 0; | ||
| 349 | } | ||
| 350 | tok = s + 1; | ||
| 351 | goto cont; | ||
| 352 | } | ||
| 353 | |||
| 354 | if (c & IN6PTON_DOT) { | ||
| 355 | ret = in4_pton(tok ? tok : s, srclen + (int)(s - tok), d, delim, &s); | ||
| 356 | if (ret > 0) { | ||
| 357 | d += 4; | ||
| 358 | break; | ||
| 359 | } | ||
| 360 | goto out; | ||
| 361 | } | ||
| 362 | |||
| 363 | w = (w << 4) | (0xff & c); | ||
| 364 | state = IN6PTON_COLON_1 | IN6PTON_DELIM; | ||
| 365 | if (!(w & 0xf000)) { | ||
| 366 | state |= IN6PTON_XDIGIT; | ||
| 367 | } | ||
| 368 | if (!dc && d + 2 < dbuf + sizeof(dbuf)) { | ||
| 369 | state |= IN6PTON_COLON_1_2; | ||
| 370 | state &= ~IN6PTON_DELIM; | ||
| 371 | } | ||
| 372 | if (d + 2 >= dbuf + sizeof(dbuf)) { | ||
| 373 | state &= ~(IN6PTON_COLON_1|IN6PTON_COLON_1_2); | ||
| 374 | } | ||
| 375 | cont: | ||
| 376 | if ((dc && d + 4 < dbuf + sizeof(dbuf)) || | ||
| 377 | d + 4 == dbuf + sizeof(dbuf)) { | ||
| 378 | state |= IN6PTON_DOT; | ||
| 379 | } | ||
| 380 | if (d >= dbuf + sizeof(dbuf)) { | ||
| 381 | state &= ~(IN6PTON_XDIGIT|IN6PTON_COLON_MASK); | ||
| 382 | } | ||
| 383 | s++; | ||
| 384 | srclen--; | ||
| 385 | } | ||
| 386 | |||
| 387 | i = 15; d--; | ||
| 388 | |||
| 389 | if (dc) { | ||
| 390 | while(d >= dc) | ||
| 391 | dst[i--] = *d--; | ||
| 392 | while(i >= dc - dbuf) | ||
| 393 | dst[i--] = 0; | ||
| 394 | while(i >= 0) | ||
| 395 | dst[i--] = *d--; | ||
| 396 | } else | ||
| 397 | memcpy(dst, dbuf, sizeof(dbuf)); | ||
| 398 | |||
| 399 | ret = 1; | ||
| 400 | out: | ||
| 401 | if (end) | ||
| 402 | *end = s; | ||
| 403 | return ret; | ||
| 404 | } | ||
| 405 | |||
| 406 | EXPORT_SYMBOL(in6_pton); | ||
| @@ -72,7 +72,6 @@ · 71 unmodified lines | |||
| 72 | 72 | ||
| 73 | /***************************** INCLUDES *****************************/ | 73 | /***************************** INCLUDES *****************************/ |
| 74 | 74 | ||
| 75 | #include <linux/config.h> /* Not needed ??? */ | ||
| 76 | #include <linux/module.h> | 75 | #include <linux/module.h> |
| 77 | #include <linux/types.h> /* off_t */ | 76 | #include <linux/types.h> /* off_t */ |
| 78 | #include <linux/netdevice.h> /* struct ifreq, dev_get_by_name() */ | 77 | #include <linux/netdevice.h> /* struct ifreq, dev_get_by_name() */ |
| @@ -86,6 +85,7 @@ · 7 unmodified lines | |||
| 86 | 85 | ||
| 87 | #include <linux/wireless.h> /* Pretty obvious */ | 86 | #include <linux/wireless.h> /* Pretty obvious */ |
| 88 | #include <net/iw_handler.h> /* New driver API */ | 87 | #include <net/iw_handler.h> /* New driver API */ |
| 88 | #include <net/netlink.h> | ||
| 89 | 89 | ||
| 90 | #include <asm/uaccess.h> /* copy_to_user() */ | 90 | #include <asm/uaccess.h> /* copy_to_user() */ |
| 91 | 91 | ||
| @@ -1850,7 +1850,7 @@ static void wireless_nlevent_process(unsigned long data) · 1758 unmodified lines | |||
| 1850 | struct sk_buff *skb; | 1850 | struct sk_buff *skb; |
| 1851 | 1851 | ||
| 1852 | while ((skb = skb_dequeue(&wireless_nlevent_queue))) | 1852 | while ((skb = skb_dequeue(&wireless_nlevent_queue))) |
| 1853 | netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_ATOMIC); | 1853 | rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); |
| 1854 | } | 1854 | } |
| 1855 | 1855 | ||
| 1856 | static DECLARE_TASKLET(wireless_nlevent_tasklet, wireless_nlevent_process, 0); | 1856 | static DECLARE_TASKLET(wireless_nlevent_tasklet, wireless_nlevent_process, 0); |
| @@ -142,14 +142,13 @@ struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority) · 141 unmodified lines | |||
| 142 | struct dccp_ackvec *av = kmem_cache_alloc(dccp_ackvec_slab, priority); | 142 | struct dccp_ackvec *av = kmem_cache_alloc(dccp_ackvec_slab, priority); |
| 143 | 143 | ||
| 144 | if (av != NULL) { | 144 | if (av != NULL) { |
| 145 | av->dccpav_buf_head = | 145 | av->dccpav_buf_head = DCCP_MAX_ACKVEC_LEN - 1; |
| 146 | av->dccpav_buf_tail = DCCP_MAX_ACKVEC_LEN - 1; | ||
| 147 | av->dccpav_buf_ackno = DCCP_MAX_SEQNO + 1; | 146 | av->dccpav_buf_ackno = DCCP_MAX_SEQNO + 1; |
| 148 | av->dccpav_buf_nonce = av->dccpav_buf_nonce = 0; | 147 | av->dccpav_buf_nonce = av->dccpav_buf_nonce = 0; |
| 149 | av->dccpav_ack_ptr = 0; | 148 | av->dccpav_ack_ptr = 0; |
| 150 | av->dccpav_time.tv_sec = 0; | 149 | av->dccpav_time.tv_sec = 0; |
| 151 | av->dccpav_time.tv_usec = 0; | 150 | av->dccpav_time.tv_usec = 0; |
| 152 | av->dccpav_sent_len = av->dccpav_vec_len = 0; | 151 | av->dccpav_vec_len = 0; |
| 153 | INIT_LIST_HEAD(&av->dccpav_records); | 152 | INIT_LIST_HEAD(&av->dccpav_records); |
| 154 | } | 153 | } |
| 155 | 154 | ||
| @@ -353,11 +352,13 @@ static void dccp_ackvec_throw_record(struct dccp_ackvec *av, · 197 unmodified lines | |||
| 353 | { | 352 | { |
| 354 | struct dccp_ackvec_record *next; | 353 | struct dccp_ackvec_record *next; |
| 355 | 354 | ||
| 356 | av->dccpav_buf_tail = avr->dccpavr_ack_ptr - 1; | 355 | /* sort out vector length */ |
| 357 | if (av->dccpav_buf_tail == 0) | 356 | if (av->dccpav_buf_head <= avr->dccpavr_ack_ptr) |
| 358 | av->dccpav_buf_tail = DCCP_MAX_ACKVEC_LEN - 1; | 357 | av->dccpav_vec_len = avr->dccpavr_ack_ptr - av->dccpav_buf_head; |
| 359 | 358 | else | |
| 360 | av->dccpav_vec_len -= avr->dccpavr_sent_len; | 359 | av->dccpav_vec_len = DCCP_MAX_ACKVEC_LEN - 1 |
| 360 | - av->dccpav_buf_head | ||
| 361 | + avr->dccpavr_ack_ptr; | ||
| 361 | 362 | ||
| 362 | /* free records */ | 363 | /* free records */ |
| 363 | list_for_each_entry_safe_from(avr, next, &av->dccpav_records, | 364 | list_for_each_entry_safe_from(avr, next, &av->dccpav_records, |
| @@ -434,8 +435,7 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av, · 70 unmodified lines | |||
| 434 | break; | 435 | break; |
| 435 | found: | 436 | found: |
| 436 | if (between48(avr->dccpavr_ack_seqno, ackno_end_rl, ackno)) { | 437 | if (between48(avr->dccpavr_ack_seqno, ackno_end_rl, ackno)) { |
| 437 | const u8 state = (*vector & | 438 | const u8 state = *vector & DCCP_ACKVEC_STATE_MASK; |
| 438 | DCCP_ACKVEC_STATE_MASK) >> 6; | ||
| 439 | if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) { | 439 | if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) { |
| 440 | #ifdef CONFIG_IP_DCCP_DEBUG | 440 | #ifdef CONFIG_IP_DCCP_DEBUG |
| 441 | struct dccp_sock *dp = dccp_sk(sk); | 441 | struct dccp_sock *dp = dccp_sk(sk); |
| @@ -54,9 +54,7 @@ struct dccp_ackvec { · 53 unmodified lines | |||
| 54 | struct list_head dccpav_records; | 54 | struct list_head dccpav_records; |
| 55 | struct timeval dccpav_time; | 55 | struct timeval dccpav_time; |
| 56 | u8 dccpav_buf_head; | 56 | u8 dccpav_buf_head; |
| 57 | u8 dccpav_buf_tail; | ||
| 58 | u8 dccpav_ack_ptr; | 57 | u8 dccpav_ack_ptr; |
| 59 | u8 dccpav_sent_len; | ||
| 60 | u8 dccpav_vec_len; | 58 | u8 dccpav_vec_len; |
| 61 | u8 dccpav_buf_nonce; | 59 | u8 dccpav_buf_nonce; |
| 62 | u8 dccpav_ack_nonce; | 60 | u8 dccpav_ack_nonce; |
| @@ -107,7 +105,7 @@ extern int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb); · 44 unmodified lines | |||
| 107 | 105 | ||
| 108 | static inline int dccp_ackvec_pending(const struct dccp_ackvec *av) | 106 | static inline int dccp_ackvec_pending(const struct dccp_ackvec *av) |
| 109 | { | 107 | { |
| 110 | return av->dccpav_sent_len != av->dccpav_vec_len; | 108 | return av->dccpav_vec_len; |
| 111 | } | 109 | } |
| 112 | #else /* CONFIG_IP_DCCP_ACKVEC */ | 110 | #else /* CONFIG_IP_DCCP_ACKVEC */ |
| 113 | static inline int dccp_ackvec_init(void) | 111 | static inline int dccp_ackvec_init(void) |
| @@ -30,6 +30,14 @@ config IP_DCCP_CCID2 · 29 unmodified lines | |||
| 30 | 30 | ||
| 31 | If in doubt, say M. | 31 | If in doubt, say M. |
| 32 | 32 | ||
| 33 | config IP_DCCP_CCID2_DEBUG | ||
| 34 | bool "CCID2 debug" | ||
| 35 | depends on IP_DCCP_CCID2 | ||
| 36 | ---help--- | ||
| 37 | Enable CCID2 debug messages. | ||
| 38 | |||
| 39 | If in doubt, say N. | ||
| 40 | |||
| 33 | config IP_DCCP_CCID3 | 41 | config IP_DCCP_CCID3 |
| 34 | tristate "CCID3 (TCP-Friendly) (EXPERIMENTAL)" | 42 | tristate "CCID3 (TCP-Friendly) (EXPERIMENTAL)" |
| 35 | depends on IP_DCCP | 43 | depends on IP_DCCP |
| @@ -27,7 +27,6 @@ · 26 unmodified lines | |||
| 27 | * | 27 | * |
| 28 | * BUGS: | 28 | * BUGS: |
| 29 | * - sequence number wrapping | 29 | * - sequence number wrapping |
| 30 | * - jiffies wrapping | ||
| 31 | */ | 30 | */ |
| 32 | 31 | ||
| 33 | #include "../ccid.h" | 32 | #include "../ccid.h" |
| @@ -36,8 +35,7 @@ · 2 unmodified lines | |||
| 36 | 35 | ||
| 37 | static int ccid2_debug; | 36 | static int ccid2_debug; |
| 38 | 37 | ||
| 39 | #undef CCID2_DEBUG | 38 | #ifdef CONFIG_IP_DCCP_CCID2_DEBUG |
| 40 | #ifdef CCID2_DEBUG | ||
| 41 | #define ccid2_pr_debug(format, a...) \ | 39 | #define ccid2_pr_debug(format, a...) \ |
| 42 | do { if (ccid2_debug) \ | 40 | do { if (ccid2_debug) \ |
| 43 | printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \ | 41 | printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \ |
| @@ -46,9 +44,7 @@ static int ccid2_debug; · 2 unmodified lines | |||
| 46 | #define ccid2_pr_debug(format, a...) | 44 | #define ccid2_pr_debug(format, a...) |
| 47 | #endif | 45 | #endif |
| 48 | 46 | ||
| 49 | static const int ccid2_seq_len = 128; | 47 | #ifdef CONFIG_IP_DCCP_CCID2_DEBUG |
| 50 | |||
| 51 | #ifdef CCID2_DEBUG | ||
| 52 | static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx) | 48 | static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx) |
| 53 | { | 49 | { |
| 54 | int len = 0; | 50 | int len = 0; |
| @@ -71,8 +67,8 @@ static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx) · 16 unmodified lines | |||
| 71 | 67 | ||
| 72 | /* packets are sent sequentially */ | 68 | /* packets are sent sequentially */ |
| 73 | BUG_ON(seqp->ccid2s_seq <= prev->ccid2s_seq); | 69 | BUG_ON(seqp->ccid2s_seq <= prev->ccid2s_seq); |
| 74 | BUG_ON(seqp->ccid2s_sent < prev->ccid2s_sent); | 70 | BUG_ON(time_before(seqp->ccid2s_sent, |
| 75 | BUG_ON(len > ccid2_seq_len); | 71 | prev->ccid2s_sent)); |
| 76 | 72 | ||
| 77 | seqp = prev; | 73 | seqp = prev; |
| 78 | } | 74 | } |
| @@ -84,16 +80,57 @@ static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx) · 5 unmodified lines | |||
| 84 | do { | 80 | do { |
| 85 | seqp = seqp->ccid2s_prev; | 81 | seqp = seqp->ccid2s_prev; |
| 86 | len++; | 82 | len++; |
| 87 | BUG_ON(len > ccid2_seq_len); | ||
| 88 | } while (seqp != hctx->ccid2hctx_seqh); | 83 | } while (seqp != hctx->ccid2hctx_seqh); |
| 89 | 84 | ||
| 90 | BUG_ON(len != ccid2_seq_len); | ||
| 91 | ccid2_pr_debug("total len=%d\n", len); | 85 | ccid2_pr_debug("total len=%d\n", len); |
| 86 | BUG_ON(len != hctx->ccid2hctx_seqbufc * CCID2_SEQBUF_LEN); | ||
| 92 | } | 87 | } |
| 93 | #else | 88 | #else |
| 94 | #define ccid2_hc_tx_check_sanity(hctx) do {} while (0) | 89 | #define ccid2_hc_tx_check_sanity(hctx) do {} while (0) |
| 95 | #endif | 90 | #endif |
| 96 | 91 | ||
| 92 | static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hctx, int num, | ||
| 93 | gfp_t gfp) | ||
| 94 | { | ||
| 95 | struct ccid2_seq *seqp; | ||
| 96 | int i; | ||
| 97 | |||
| 98 | /* check if we have space to preserve the pointer to the buffer */ | ||
| 99 | if (hctx->ccid2hctx_seqbufc >= (sizeof(hctx->ccid2hctx_seqbuf) / | ||
| 100 | sizeof(struct ccid2_seq*))) | ||
| 101 | return -ENOMEM; | ||
| 102 | |||
| 103 | /* allocate buffer and initialize linked list */ | ||
| 104 | seqp = kmalloc(sizeof(*seqp) * num, gfp); | ||
| 105 | if (seqp == NULL) | ||
| 106 | return -ENOMEM; | ||
| 107 | |||
| 108 | for (i = 0; i < (num - 1); i++) { | ||
| 109 | seqp[i].ccid2s_next = &seqp[i + 1]; | ||
| 110 | seqp[i + 1].ccid2s_prev = &seqp[i]; | ||
| 111 | } | ||
| 112 | seqp[num - 1].ccid2s_next = seqp; | ||
| 113 | seqp->ccid2s_prev = &seqp[num - 1]; | ||
| 114 | |||
| 115 | /* This is the first allocation. Initiate the head and tail. */ | ||
| 116 | if (hctx->ccid2hctx_seqbufc == 0) | ||
| 117 | hctx->ccid2hctx_seqh = hctx->ccid2hctx_seqt = seqp; | ||
| 118 | else { | ||
| 119 | /* link the existing list with the one we just created */ | ||
| 120 | hctx->ccid2hctx_seqh->ccid2s_next = seqp; | ||
| 121 | seqp->ccid2s_prev = hctx->ccid2hctx_seqh; | ||
| 122 | |||
| 123 | hctx->ccid2hctx_seqt->ccid2s_prev = &seqp[num - 1]; | ||
| 124 | seqp[num - 1].ccid2s_next = hctx->ccid2hctx_seqt; | ||
| 125 | } | ||
| 126 | |||
| 127 | /* store the original pointer to the buffer so we can free it */ | ||
| 128 | hctx->ccid2hctx_seqbuf[hctx->ccid2hctx_seqbufc] = seqp; | ||
| 129 | hctx->ccid2hctx_seqbufc++; | ||
| 130 | |||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 97 | static int ccid2_hc_tx_send_packet(struct sock *sk, | 134 | static int ccid2_hc_tx_send_packet(struct sock *sk, |
| 98 | struct sk_buff *skb, int len) | 135 | struct sk_buff *skb, int len) |
| 99 | { | 136 | { |
| @@ -122,7 +159,7 @@ static int ccid2_hc_tx_send_packet(struct sock *sk, · 22 unmodified lines | |||
| 122 | } | 159 | } |
| 123 | } | 160 | } |
| 124 | 161 | ||
| 125 | return 100; /* XXX */ | 162 | return 1; /* XXX CCID should dequeue when ready instead of polling */ |
| 126 | } | 163 | } |
| 127 | 164 | ||
| 128 | static void ccid2_change_l_ack_ratio(struct sock *sk, int val) | 165 | static void ccid2_change_l_ack_ratio(struct sock *sk, int val) |
| @@ -150,10 +187,8 @@ static void ccid2_change_l_ack_ratio(struct sock *sk, int val) · 21 unmodified lines | |||
| 150 | dp->dccps_l_ack_ratio = val; | 187 | dp->dccps_l_ack_ratio = val; |
| 151 | } | 188 | } |
| 152 | 189 | ||
| 153 | static void ccid2_change_cwnd(struct sock *sk, int val) | 190 | static void ccid2_change_cwnd(struct ccid2_hc_tx_sock *hctx, int val) |
| 154 | { | 191 | { |
| 155 | struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk); | ||
| 156 | |||
| 157 | if (val == 0) | 192 | if (val == 0) |
| 158 | val = 1; | 193 | val = 1; |
| 159 | 194 | ||
| @@ -164,6 +199,17 @@ static void ccid2_change_cwnd(struct sock *sk, int val) · 4 unmodified lines | |||
| 164 | hctx->ccid2hctx_cwnd = val; | 199 | hctx->ccid2hctx_cwnd = val; |
| 165 | } | 200 | } |
| 166 | 201 | ||
| 202 | static void ccid2_change_srtt(struct ccid2_hc_tx_sock *hctx, long val) | ||
| 203 | { | ||
| 204 | ccid2_pr_debug("change SRTT to %ld\n", val); | ||
| 205 | hctx->ccid2hctx_srtt = val; | ||
| 206 | } | ||
| 207 | |||
| 208 | static void ccid2_change_pipe(struct ccid2_hc_tx_sock *hctx, long val) | ||
| 209 | { | ||
| 210 | hctx->ccid2hctx_pipe = val; | ||
| 211 | } | ||
| 212 | |||
| 167 | static void ccid2_start_rto_timer(struct sock *sk); | 213 | static void ccid2_start_rto_timer(struct sock *sk); |
| 168 | 214 | ||
| 169 | static void ccid2_hc_tx_rto_expire(unsigned long data) | 215 | static void ccid2_hc_tx_rto_expire(unsigned long data) |
| @@ -193,11 +239,11 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) · 23 unmodified lines | |||
| 193 | ccid2_start_rto_timer(sk); | 239 | ccid2_start_rto_timer(sk); |
| 194 | 240 | ||
| 195 | /* adjust pipe, cwnd etc */ | 241 | /* adjust pipe, cwnd etc */ |
| 196 | hctx->ccid2hctx_pipe = 0; | 242 | ccid2_change_pipe(hctx, 0); |
| 197 | hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd >> 1; | 243 | hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd >> 1; |
| 198 | if (hctx->ccid2hctx_ssthresh < 2) | 244 | if (hctx->ccid2hctx_ssthresh < 2) |
| 199 | hctx->ccid2hctx_ssthresh = 2; | 245 | hctx->ccid2hctx_ssthresh = 2; |
| 200 | ccid2_change_cwnd(sk, 1); | 246 | ccid2_change_cwnd(hctx, 1); |
| 201 | 247 | ||
| 202 | /* clear state about stuff we sent */ | 248 | /* clear state about stuff we sent */ |
| 203 | hctx->ccid2hctx_seqt = hctx->ccid2hctx_seqh; | 249 | hctx->ccid2hctx_seqt = hctx->ccid2hctx_seqh; |
| @@ -232,13 +278,14 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, int len) · 28 unmodified lines | |||
| 232 | { | 278 | { |
| 233 | struct dccp_sock *dp = dccp_sk(sk); | 279 | struct dccp_sock *dp = dccp_sk(sk); |
| 234 | struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk); | 280 | struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk); |
| 281 | struct ccid2_seq *next; | ||
| 235 | u64 seq; | 282 | u64 seq; |
| 236 | 283 | ||
| 237 | ccid2_hc_tx_check_sanity(hctx); | 284 | ccid2_hc_tx_check_sanity(hctx); |
| 238 | 285 | ||
| 239 | BUG_ON(!hctx->ccid2hctx_sendwait); | 286 | BUG_ON(!hctx->ccid2hctx_sendwait); |
| 240 | hctx->ccid2hctx_sendwait = 0; | 287 | hctx->ccid2hctx_sendwait = 0; |
| 241 | hctx->ccid2hctx_pipe++; | 288 | ccid2_change_pipe(hctx, hctx->ccid2hctx_pipe + 1); |
| 242 | BUG_ON(hctx->ccid2hctx_pipe < 0); | 289 | BUG_ON(hctx->ccid2hctx_pipe < 0); |
| 243 | 290 | ||
| 244 | /* There is an issue. What if another packet is sent between | 291 | /* There is an issue. What if another packet is sent between |
| @@ -251,15 +298,23 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, int len) · 6 unmodified lines | |||
| 251 | hctx->ccid2hctx_seqh->ccid2s_seq = seq; | 298 | hctx->ccid2hctx_seqh->ccid2s_seq = seq; |
| 252 | hctx->ccid2hctx_seqh->ccid2s_acked = 0; | 299 | hctx->ccid2hctx_seqh->ccid2s_acked = 0; |
| 253 | hctx->ccid2hctx_seqh->ccid2s_sent = jiffies; | 300 | hctx->ccid2hctx_seqh->ccid2s_sent = jiffies; |
| 254 | hctx->ccid2hctx_seqh = hctx->ccid2hctx_seqh->ccid2s_next; | ||
| 255 | 301 | ||
| 256 | ccid2_pr_debug("cwnd=%d pipe=%d\n", hctx->ccid2hctx_cwnd, | 302 | next = hctx->ccid2hctx_seqh->ccid2s_next; |
| 257 | hctx->ccid2hctx_pipe); | 303 | /* check if we need to alloc more space */ |
| 304 | if (next == hctx->ccid2hctx_seqt) { | ||
| 305 | int rc; | ||
| 306 | |||
| 307 | ccid2_pr_debug("allocating more space in history\n"); | ||
| 308 | rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, GFP_KERNEL); | ||
| 309 | BUG_ON(rc); /* XXX what do we do? */ | ||
| 258 | 310 | ||
| 259 | if (hctx->ccid2hctx_seqh == hctx->ccid2hctx_seqt) { | 311 | next = hctx->ccid2hctx_seqh->ccid2s_next; |
| 260 | /* XXX allocate more space */ | 312 | BUG_ON(next == hctx->ccid2hctx_seqt); |
| 261 | WARN_ON(1); | ||
| 262 | } | 313 | } |
| 314 | hctx->ccid2hctx_seqh = next; | ||
| 315 | |||
| 316 | ccid2_pr_debug("cwnd=%d pipe=%d\n", hctx->ccid2hctx_cwnd, | ||
| 317 | hctx->ccid2hctx_pipe); | ||
| 263 | 318 | ||
| 264 | hctx->ccid2hctx_sent++; | 319 | hctx->ccid2hctx_sent++; |
| 265 | 320 | ||
| @@ -295,7 +350,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, int len) · 29 unmodified lines | |||
| 295 | if (!timer_pending(&hctx->ccid2hctx_rtotimer)) | 350 | if (!timer_pending(&hctx->ccid2hctx_rtotimer)) |
| 296 | ccid2_start_rto_timer(sk); | 351 | ccid2_start_rto_timer(sk); |
| 297 | 352 | ||
| 298 | #ifdef CCID2_DEBUG | 353 | #ifdef CONFIG_IP_DCCP_CCID2_DEBUG |
| 299 | ccid2_pr_debug("pipe=%d\n", hctx->ccid2hctx_pipe); | 354 | ccid2_pr_debug("pipe=%d\n", hctx->ccid2hctx_pipe); |
| 300 | ccid2_pr_debug("Sent: seq=%llu\n", seq); | 355 | ccid2_pr_debug("Sent: seq=%llu\n", seq); |
| 301 | do { | 356 | do { |
| @@ -398,7 +453,7 @@ static inline void ccid2_new_ack(struct sock *sk, · 96 unmodified lines | |||
| 398 | /* increase every 2 acks */ | 453 | /* increase every 2 acks */ |
| 399 | hctx->ccid2hctx_ssacks++; | 454 | hctx->ccid2hctx_ssacks++; |
| 400 | if (hctx->ccid2hctx_ssacks == 2) { | 455 | if (hctx->ccid2hctx_ssacks == 2) { |
| 401 | ccid2_change_cwnd(sk, hctx->ccid2hctx_cwnd + 1); | 456 | ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd+1); |
| 402 | hctx->ccid2hctx_ssacks = 0; | 457 | hctx->ccid2hctx_ssacks = 0; |
| 403 | *maxincr = *maxincr - 1; | 458 | *maxincr = *maxincr - 1; |
| 404 | } | 459 | } |
| @@ -411,26 +466,28 @@ static inline void ccid2_new_ack(struct sock *sk, · 6 unmodified lines | |||
| 411 | hctx->ccid2hctx_acks++; | 466 | hctx->ccid2hctx_acks++; |
| 412 | 467 | ||
| 413 | if (hctx->ccid2hctx_acks >= hctx->ccid2hctx_cwnd) { | 468 | if (hctx->ccid2hctx_acks >= hctx->ccid2hctx_cwnd) { |
| 414 | ccid2_change_cwnd(sk, hctx->ccid2hctx_cwnd + 1); | 469 | ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd + 1); |
| 415 | hctx->ccid2hctx_acks = 0; | 470 | hctx->ccid2hctx_acks = 0; |
| 416 | } | 471 | } |
| 417 | } | 472 | } |
| 418 | 473 | ||
| 419 | /* update RTO */ | 474 | /* update RTO */ |
| 420 | if (hctx->ccid2hctx_srtt == -1 || | 475 | if (hctx->ccid2hctx_srtt == -1 || |
| 421 | (jiffies - hctx->ccid2hctx_lastrtt) >= hctx->ccid2hctx_srtt) { | 476 | time_after(jiffies, hctx->ccid2hctx_lastrtt + hctx->ccid2hctx_srtt)) { |
| 422 | unsigned long r = jiffies - seqp->ccid2s_sent; | 477 | unsigned long r = (long)jiffies - (long)seqp->ccid2s_sent; |
| 423 | int s; | 478 | int s; |
| 424 | 479 | ||
| 425 | /* first measurement */ | 480 | /* first measurement */ |
| 426 | if (hctx->ccid2hctx_srtt == -1) { | 481 | if (hctx->ccid2hctx_srtt == -1) { |
| 427 | ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n", | 482 | ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n", |
| 428 | r, jiffies, seqp->ccid2s_seq); | 483 | r, jiffies, seqp->ccid2s_seq); |
| 429 | hctx->ccid2hctx_srtt = r; | 484 | ccid2_change_srtt(hctx, r); |
| 430 | hctx->ccid2hctx_rttvar = r >> 1; | 485 | hctx->ccid2hctx_rttvar = r >> 1; |
| 431 | } else { | 486 | } else { |
| 432 | /* RTTVAR */ | 487 | /* RTTVAR */ |
| 433 | long tmp = hctx->ccid2hctx_srtt - r; | 488 | long tmp = hctx->ccid2hctx_srtt - r; |
| 489 | long srtt; | ||
| 490 | |||
| 434 | if (tmp < 0) | 491 | if (tmp < 0) |
| 435 | tmp *= -1; | 492 | tmp *= -1; |
| 436 | 493 | ||
| @@ -440,10 +497,12 @@ static inline void ccid2_new_ack(struct sock *sk, · 3 unmodified lines | |||
| 440 | hctx->ccid2hctx_rttvar += tmp; | 497 | hctx->ccid2hctx_rttvar += tmp; |
| 441 | 498 | ||
| 442 | /* SRTT */ | 499 | /* SRTT */ |
| 443 | hctx->ccid2hctx_srtt *= 7; | 500 | srtt = hctx->ccid2hctx_srtt; |
| 444 | hctx->ccid2hctx_srtt >>= 3; | 501 | srtt *= 7; |
| 502 | srtt >>= 3; | ||
| 445 | tmp = r >> 3; | 503 | tmp = r >> 3; |
| 446 | hctx->ccid2hctx_srtt += tmp; | 504 | srtt += tmp; |
| 505 | ccid2_change_srtt(hctx, srtt); | ||
| 447 | } | 506 | } |
| 448 | s = hctx->ccid2hctx_rttvar << 2; | 507 | s = hctx->ccid2hctx_rttvar << 2; |
| 449 | /* clock granularity is 1 when based on jiffies */ | 508 | /* clock granularity is 1 when based on jiffies */ |
| @@ -479,13 +538,29 @@ static void ccid2_hc_tx_dec_pipe(struct sock *sk) · 29 unmodified lines | |||
| 479 | { | 538 | { |
| 480 | struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk); | 539 | struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk); |
| 481 | 540 | ||
| 482 | hctx->ccid2hctx_pipe--; | 541 | ccid2_change_pipe(hctx, hctx->ccid2hctx_pipe-1); |
| 483 | BUG_ON(hctx->ccid2hctx_pipe < 0); | 542 | BUG_ON(hctx->ccid2hctx_pipe < 0); |
| 484 | 543 | ||
| 485 | if (hctx->ccid2hctx_pipe == 0) | 544 | if (hctx->ccid2hctx_pipe == 0) |
| 486 | ccid2_hc_tx_kill_rto_timer(sk); | 545 | ccid2_hc_tx_kill_rto_timer(sk); |
| 487 | } | 546 | } |
| 488 | 547 | ||
| 548 | static void ccid2_congestion_event(struct ccid2_hc_tx_sock *hctx, | ||
| 549 | struct ccid2_seq *seqp) | ||
| 550 | { | ||
| 551 | if (time_before(seqp->ccid2s_sent, hctx->ccid2hctx_last_cong)) { | ||
| 552 | ccid2_pr_debug("Multiple losses in an RTT---treating as one\n"); | ||
| 553 | return; | ||
| 554 | } | ||
| 555 | |||
| 556 | hctx->ccid2hctx_last_cong = jiffies; | ||
| 557 | |||
| 558 | ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd >> 1); | ||
| 559 | hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd; | ||
| 560 | if (hctx->ccid2hctx_ssthresh < 2) | ||
| 561 | hctx->ccid2hctx_ssthresh = 2; | ||
| 562 | } | ||
| 563 | |||
126 more lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 173 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 612 lines aren’t shown here.
This diff is large: its 305 lines aren’t shown here.
This diff is large: its 334 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 1608 lines aren’t shown here.
This diff is large: its 390 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 604 lines aren’t shown here.
This diff is large: its 300 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 727 lines aren’t shown here.
This diff is large: its 806 lines aren’t shown here.
This diff is large: its 284 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 407 lines aren’t shown here.
This diff is large: its 782 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 156 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 265 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 400 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 230 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 265 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 219 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 1089 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 157 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 374 lines aren’t shown here.
This diff is large: its 306 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 732 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 168 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 520 lines aren’t shown here.
This diff is large: its 172 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 221 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 1740 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 164 lines aren’t shown here.
This diff is large: its 214 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 183 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 381 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 340 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 193 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 264 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 139 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 158 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 138 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 543 lines aren’t shown here.
This diff is large: its 218 lines aren’t shown here.
This diff is large: its 514 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 232 lines aren’t shown here.
This diff is large: its 625 lines aren’t shown here.
This diff is large: its 247 lines aren’t shown here.
This diff is large: its 254 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 159 lines aren’t shown here.
This diff is large: its 216 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 184 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 317 lines aren’t shown here.
This diff is large: its 241 lines aren’t shown here.
This diff is large: its 343 lines aren’t shown here.
This diff is large: its 273 lines aren’t shown here.
This diff is large: its 288 lines aren’t shown here.
This diff is large: its 750 lines aren’t shown here.
This diff is large: its 207 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 2127 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 449 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 265 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 2046 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 347 lines aren’t shown here.
This diff is large: its 378 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 160 lines aren’t shown here.
This diff is large: its 294 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 1413 lines aren’t shown here.
This diff is large: its 1012 lines aren’t shown here.
This diff is large: its 625 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 447 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 194 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 659 lines aren’t shown here.
This diff is large: its 321 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 370 lines aren’t shown here.
This diff is large: its 266 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 215 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 206 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 234 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 153 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 1092 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 678 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 307 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 622 lines aren’t shown here.
This diff is large: its 191 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 153 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 179 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 297 lines aren’t shown here.
This diff is large: its 331 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 743 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 1288 lines aren’t shown here.
This diff is large: its 327 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 128 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 1588 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 138 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.