draft-ietf-dhc-stable-privacy-addresses-00.txt | draft-ietf-dhc-stable-privacy-addresses-01.txt | |||
---|---|---|---|---|
Dynamic Host Configuration (dhc) F. Gont | Dynamic Host Configuration (dhc) F. Gont | |||
Internet-Draft SI6 Networks / UTN-FRH | Internet-Draft SI6 Networks / UTN-FRH | |||
Intended status: Standards Track W. Liu | Intended status: Standards Track W. Liu | |||
Expires: April 4, 2015 Huawei Technologies | Expires: August 22, 2015 Huawei Technologies | |||
October 1, 2014 | February 18, 2015 | |||
A Method for Generating Semantically Opaque Interface Identifiers with | A Method for Generating Semantically Opaque Interface Identifiers with | |||
Dynamic Host Configuration Protocol for IPv6 (DHCPv6) | Dynamic Host Configuration Protocol for IPv6 (DHCPv6) | |||
draft-ietf-dhc-stable-privacy-addresses-00 | draft-ietf-dhc-stable-privacy-addresses-01 | |||
Abstract | Abstract | |||
This document specifies a method for selecting IPv6 Interface | This document specifies a method for selecting IPv6 Interface | |||
Identifiers, to be employed by Dynamic Host Configuration Protocol | Identifiers, to be employed by Dynamic Host Configuration Protocol | |||
for IPv6 (DHCPv6) servers when leasing non-temporary IPv6 addresses | for IPv6 (DHCPv6) servers when leasing non-temporary IPv6 addresses | |||
to DHCPv6 clients. This method is a DHCPv6 server side algorithm, | to DHCPv6 clients. This method is a DHCPv6 server side algorithm, | |||
that does not require any updates to the existing DHCPv6 | that does not require any updates to the existing DHCPv6 | |||
specifications. The aforementioned method results in stable | specifications. The aforementioned method results in stable | |||
addresses within each subnet, even in the presence of multiple DHCPv6 | addresses within each subnet, even in the presence of multiple DHCPv6 | |||
servers or even DHCPv6 server reinstallments. It is a DHCPv6-variant | servers or DHCPv6 server reinstallments. It is a DHCPv6-variant of | |||
of the method specified in RFC 7217 for IPv6 Stateless Address | the method specified in RFC 7217 for IPv6 Stateless Address | |||
Autoconfiguration. | Autoconfiguration. | |||
Status of This Memo | Status of This Memo | |||
This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
Drafts is at http://datatracker.ietf.org/drafts/current/. | Drafts is at http://datatracker.ietf.org/drafts/current/. | |||
Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
This Internet-Draft will expire on April 4, 2015. | This Internet-Draft will expire on August 22, 2015. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2014 IETF Trust and the persons identified as the | Copyright (c) 2015 IETF Trust and the persons identified as the | |||
document authors. All rights reserved. | document authors. All rights reserved. | |||
This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
(http://trustee.ietf.org/license-info) in effect on the date of | (http://trustee.ietf.org/license-info) in effect on the date of | |||
publication of this document. Please review these documents | publication of this document. Please review these documents | |||
carefully, as they describe your rights and restrictions with respect | carefully, as they describe your rights and restrictions with respect | |||
to this document. Code Components extracted from this document must | to this document. Code Components extracted from this document must | |||
include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
described in the Simplified BSD License. | described in the Simplified BSD License. | |||
Table of Contents | Table of Contents | |||
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 | |||
2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 | 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
3. Method Specification . . . . . . . . . . . . . . . . . . . . 3 | 3. Method Specification . . . . . . . . . . . . . . . . . . . . 3 | |||
4. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 6 | 4. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 6 | |||
5. Security Considerations . . . . . . . . . . . . . . . . . . . 6 | 5. Security Considerations . . . . . . . . . . . . . . . . . . . 6 | |||
6. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 6 | 6. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 7 | |||
7. References . . . . . . . . . . . . . . . . . . . . . . . . . 7 | 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 7 | |||
7.1. Normative References . . . . . . . . . . . . . . . . . . 7 | 7.1. Normative References . . . . . . . . . . . . . . . . . . 7 | |||
7.2. Informative References . . . . . . . . . . . . . . . . . 7 | 7.2. Informative References . . . . . . . . . . . . . . . . . 7 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 8 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 8 | |||
1. Introduction | 1. Introduction | |||
Stable IPv6 addresses tend to simplify event logging, trouble- | Stable IPv6 addresses tend to simplify event logging, trouble- | |||
shooting, enforcement of access controls and quality of service, etc. | shooting, enforcement of access controls and quality of service, etc. | |||
However, there are a number of scenarios in which a host employing | However, there are a number of scenarios in which a host employing | |||
skipping to change at page 2, line 48 | skipping to change at page 2, line 48 | |||
for IPv6 (DHCPv6) servers when leasing non-temporary IPv6 addresses | for IPv6 (DHCPv6) servers when leasing non-temporary IPv6 addresses | |||
to DHCPv6 clients (i.e., to be employed with IA_NA options). This | to DHCPv6 clients (i.e., to be employed with IA_NA options). This | |||
method is a DHCPv6 server side algorithm, that does not require any | method is a DHCPv6 server side algorithm, that does not require any | |||
updates to the existing DHCPv6 specifications. The aforementioned | updates to the existing DHCPv6 specifications. The aforementioned | |||
method has the following properties: | method has the following properties: | |||
o The resulting IPv6 addresses remain stable within each subnet for | o The resulting IPv6 addresses remain stable within each subnet for | |||
the same network interface of the same client, even when different | the same network interface of the same client, even when different | |||
DHCPv6 servers (implementing this specification) are employed. | DHCPv6 servers (implementing this specification) are employed. | |||
o It must be difficult for an outsider to predict the IPv6 addresses | o Predicting the IPv6 addresses that will be generated by the method | |||
that will be generated by the method specified in this document, | specified in this document, even with knowledge of the IPv6 | |||
even with knowledge of the IPv6 addresses generated for other | addresses generated for other nodes within the same network, | |||
nodes within the same network. | becomes very difficult. | |||
The method specified in this document achieves the aforementioned | The method specified in this document achieves the aforementioned | |||
goals by means of a calculated technique as opposed to e.g. state- | properties by means of a calculated technique as opposed to e.g. | |||
sharing among DHCPv6 servers . This approach has been already | state- sharing among DHCPv6 servers. This approach has been already | |||
suggested in [RFC7031]. We note that the method specified in this | suggested in [RFC7031]. We note that the method specified in this | |||
document is essentially a DHCPv6-version of the "Method for | document is essentially a DHCPv6-version of the "Method for | |||
Generating Semantically Opaque Interface Identifiers with IPv6 | Generating Semantically Opaque Interface Identifiers with IPv6 | |||
Stateless Address Autoconfiguration (SLAAC)" specified in [RFC7217]. | Stateless Address Autoconfiguration (SLAAC)" specified in [RFC7217]. | |||
2. Terminology | 2. Terminology | |||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this | |||
document are to be interpreted as described in RFC 2119 [RFC2119]. | document are to be interpreted as described in RFC 2119 [RFC2119]. | |||
skipping to change at page 3, line 29 | skipping to change at page 3, line 29 | |||
3. Method Specification | 3. Method Specification | |||
DHCPv6 server implementations conforming to this specification MUST | DHCPv6 server implementations conforming to this specification MUST | |||
generate non-temporary IPv6 addresses using the algorithm specified | generate non-temporary IPv6 addresses using the algorithm specified | |||
in this section. | in this section. | |||
Implementations conforming to this specification SHOULD provide the | Implementations conforming to this specification SHOULD provide the | |||
means for a system administrator to enable or disable the use of this | means for a system administrator to enable or disable the use of this | |||
algorithm for generating IPv6 addresses. | algorithm for generating IPv6 addresses. | |||
Unless otherwise noted, all of the parameters included in the | All of the parameters included in the expression below MUST be | |||
expression below MUST be included when generating an IPv6 address. | included when generating an IPv6 address. | |||
A DHCPv6 server implementing this specification must select the IPv6 | ||||
addresses to be leased with the following algorithm: | ||||
1. Compute a random (but stable) identifier with the expression: | 1. Compute a random (but stable) identifier with the expression: | |||
RID = F(Prefix | Client_DUID | IAID | Counter | secret_key) | RID = F(IPV6_ADDR_HI | IPV6_ADDR_LOW | Client_DUID | IAID | | |||
Counter | secret_key) | ||||
Where: | Where: | |||
RID: | RID: | |||
Random (but stable) Identifier | Random (but stable) Identifier | |||
F(): | F(): | |||
A pseudorandom function (PRF) that MUST NOT be computable from | A pseudorandom function (PRF) that MUST NOT be computable from | |||
the outside (without knowledge of the secret key). F() MUST | the outside (without knowledge of the secret key). F() MUST | |||
also be difficult to reverse, such that it resists attempts to | also be difficult to reverse, such that it resists attempts to | |||
skipping to change at page 4, line 10 | skipping to change at page 4, line 13 | |||
be implemented as a cryptographic hash of the concatenation of | be implemented as a cryptographic hash of the concatenation of | |||
each of the function parameters. The default algorithm to be | each of the function parameters. The default algorithm to be | |||
employed for F() SHOULD be SHA-1 [FIPS-SHS]. An | employed for F() SHOULD be SHA-1 [FIPS-SHS]. An | |||
implementation MAY provide the means for selecting other other | implementation MAY provide the means for selecting other other | |||
algorithms (e.g., SHA-256) for F(). Note: MD5 [RFC1321] is | algorithms (e.g., SHA-256) for F(). Note: MD5 [RFC1321] is | |||
considered unacceptable for F() [RFC6151]. | considered unacceptable for F() [RFC6151]. | |||
|: | |: | |||
An operator representing "concatenation". | An operator representing "concatenation". | |||
Prefix: | IPV6_ADDR_HI: | |||
A prefix that represents an IPv6 address pool from which the | An IPv6 address specifying the upper boundary of the IPv6 | |||
DHCPv6 server will assign addresses. That is, this algorithm | address pool from which the DHCPv6 server leases IPv6 | |||
REQUIRES that the DHCPv6 server manages all the IPv6 address | addresses. It MUST be represented as a 128-bit unsigned | |||
space within a specified prefix (as opposed to, e.g., an | integer in network byte order. If multiple servers operate on | |||
address range that cannot be represented with a prefix | the same network to provide increased availability, all such | |||
notation) and that it can be configured with such a prefix. | DHCPv6 servers MUST be configured with the address range | |||
If multiple servers operate on the same network to provide | (i.e., the same IPV6_ADDR_HI and IPV6_ADDR_LOW parameters). | |||
increased availability, all such DHCPv6 servers MUST be | It is the administrator's responsibility that the | |||
configured with the same Prefix. It is the administrator's | aforementioned requirement is met. | |||
responsibility that the aforementioned requirement is met. | ||||
IPV6_ADDR_LOW: | ||||
An IPv6 address specifying the lower boundary of the IPv6 | ||||
address pool from which the DHCPv6 server leases IPv6 | ||||
addresses. It MUST be represented as a 128-bit unsigned | ||||
integer in network byte order. If multiple servers operate on | ||||
the same network to provide increased availability, all such | ||||
DHCPv6 servers MUST be configured with the address range | ||||
(i.e., the same IPV6_ADDR_HI and IPV6_ADDR_LOW parameters). | ||||
It is the administrator's responsibility that the | ||||
aforementioned requirement is met. | ||||
Client_DUID: | Client_DUID: | |||
The DUID value contained in the Client Identifier option | The DUID value contained in the Client Identifier option | |||
received in the client message. | received in the DHCPv6 client message. The DUID can be | |||
treated as an array of 8-bit unsigned integers. | ||||
IAID: | IAID: | |||
The IAID value contained in the IA_NA option received in the | The IAID value contained in the IA_NA option received in the | |||
client message. | client message. It MUST be interpreted as a 32-bit unsigned | |||
integer in network byte order. | ||||
Counter: | Counter: | |||
A variable that is employed to resolve address conflicts. It | A 32-bit unsigned integer in network byte order, that is | |||
MUST be initialized to 0. | employed to resolve address conflicts. It MUST be initialized | |||
to 0. | ||||
secret_key: | secret_key: | |||
A secret key configured by the DHCPv6 server administrator, | A secret key configured by the DHCPv6 server administrator, | |||
which MUST NOT be known by the attacker. An implementation of | which MUST NOT be known by the attacker. It MUST be encoded | |||
as an array of 8-bit unsigned integers containing the ASCII | ||||
codes corresponding to the secret key. An implementation of | ||||
this specification MUST provide an interface for viewing and | this specification MUST provide an interface for viewing and | |||
changing the secret key. All DHCPv6 servers leasing addresses | changing the secret key. All DHCPv6 servers leasing addresses | |||
from the same Prefix MUST employ the same secret key. | from the same address range MUST employ the same secret key. | |||
2. The Interface Identifier is obtained by taking as many bits from | 2. A candidate IPv6 address to be leased is obtained as follows: | |||
the RID value (computed in the previous step) as necessary, | ||||
starting from the least significant bit. | IPV6_ADDRESS = IPV6_ADDR_LOW + RID % (IPV6_ADDR_HI - | |||
IPV6_ADDR_LOW + 1) | ||||
We note that [RFC4291] requires that, the Interface IDs of all | We note that [RFC4291] requires that, the Interface IDs of all | |||
unicast addresses (except those that start with the binary | unicast addresses (except those that start with the binary | |||
value 000) be 64-bit long. However, the method discussed in | value 000) be 64-bit long. The method discussed in this | |||
this document could be employed for generating Interface IDs | document can be employed for generating IPv6 addresses for any | |||
of any arbitrary length, albeit at the expense of reduced | address range (e.g., smaller than 2**64 bits), albeit at the | |||
entropy (when employing Interface IDs smaller than 64 bits). | expense of reduced entropy (when the address range is smaller | |||
than than of a full 64-bit subnet). | ||||
The resulting Interface Identifier MUST be compared against the | 3. The Interface Identifier of the selected IPv6 address MUST be | |||
reserved IPv6 Interface Identifiers [RFC5453] | compared against the reserved IPv6 Interface Identifiers | |||
[IANA-RESERVED-IID]. In the event that an unacceptable | [RFC5453] [IANA-RESERVED-IID]. In the event that an unacceptable | |||
identifier has been generated, the Counter variable should be | identifier has been generated, the Counter variable should be | |||
incremented by 1, and a new Interface ID should be computed with | incremented by 1, and a new IPv6 address (RID and subsequent | |||
the updated Counter value. | IPV6_ADDRESS) should be computed with the updated Counter value. | |||
3. The IPv6 address is finally obtained by concatenating the Prefix | 4. If the resulting address is not available (e.g., there is a | |||
with the Interface Identifier obtained in the previous step. If | ||||
the resulting address is not available (e.g., there is a | ||||
conflicting binding), the server should increment the Counter | conflicting binding), the server should increment the Counter | |||
variable, and a new Interface ID and IPv6 address should be | variable, and a new Interface ID and IPv6 address should be | |||
computed with the updated Counter value. | computed with the updated Counter value. | |||
This document requires that SHA-1 be the default function to be used | This document requires that SHA-1 be the default function to be used | |||
for F(), such that, all other configuration parameters being the | for F(), such that, all other configuration parameters being the | |||
same, different implementations of this specification result in the | same, different implementations of this specification result in the | |||
same IPv6 addresses. | same IPv6 addresses. | |||
Including the Prefix in the PRF computation causes the Interface | Including the address range in the PRF computation causes the | |||
Identifier to for each address from a different prefix assigned to | Interface Identifier to be different for each IPv6 address leased | |||
the same client. This mitigates the correlation of activities of | from a different address range to the same client. This mitigates | |||
multi-homed nodes (since each of the corresponding addresses will | the correlation of activities of multi-homed nodes (since each of the | |||
employ a different Interface ID), host-tracking (since the network | corresponding addresses will employ a different Interface ID), host- | |||
prefix will change as the node moves from one network to another), | tracking (since the network prefix will change as the node moves from | |||
and any other attacks that benefit from predictable Interface | one network to another), and any other attacks that benefit from | |||
Identifiers (such as IPv6 address scanning attacks) | predictable Interface Identifiers (such as IPv6 address scanning | |||
[I-D.ietf-6man-ipv6-address-generation-privacy]. | attacks) [I-D.ietf-6man-ipv6-address-generation-privacy]. | |||
As required by [RFC3315], an IAID is associated with each of the | As required by [RFC3315], an IAID is associated with each of the | |||
client's network interfaces, and is consistent across restarts of the | client's network interfaces, and is consistent across restarts of the | |||
DHCP client. | DHCPv6 client. | |||
The Counter parameter provides the means to intentionally cause this | The Counter parameter provides the means to intentionally cause this | |||
algorithm to produce a different IPv6 addresses (all other parameters | algorithm to produce different IPv6 addresses (all other parameters | |||
being the same). This could be necessary to resolve address | being the same). This could be necessary to resolve address | |||
conflicts (e.g. the resulting address having a conflicting binding). | conflicts (e.g. the resulting address having a conflicting binding). | |||
Note that the result of F() in the algorithm above is no more secure | Note that the result of F() in the algorithm above is no more secure | |||
than the secret key. If an attacker is aware of the PRF that is | than the secret key. If an attacker is aware of the PRF that is | |||
being used by the DHCPv6 server (which we should expect), and the | being used by the DHCPv6 server (which we should expect), and the | |||
attacker can obtain enough material (i.e. addresses generated by the | attacker can obtain enough material (i.e. addresses generated by the | |||
DHCPv6 server), the attacker may simply search the entire secret-key | DHCPv6 server), the attacker may simply search the entire secret-key | |||
space to find matches. To protect against this, the secret key | space to find matches. To protect against this, the secret key | |||
SHOULD be of at least 128 bits. Key lengths of at least 128 bits | SHOULD be of at least 128 bits. Key lengths of at least 128 bits | |||
skipping to change at page 6, line 43 | skipping to change at page 7, line 13 | |||
[I-D.ietf-opsec-ipv6-host-scanning] are mitigated. | [I-D.ietf-opsec-ipv6-host-scanning] are mitigated. | |||
The method specified in this document neither mitigates nor | The method specified in this document neither mitigates nor | |||
exacerbates the security considerations for DHCPv6 discussed in | exacerbates the security considerations for DHCPv6 discussed in | |||
[RFC3315]. | [RFC3315]. | |||
6. Acknowledgements | 6. Acknowledgements | |||
This document is based on [RFC7217], authored by Fernando Gont. | This document is based on [RFC7217], authored by Fernando Gont. | |||
The authors would like to thank Tatuya Jinmei for providing valuable | The authors would like to thank Stephane Bortzmeyer, Tatuya Jinmei, | |||
comments on earlier versions of this documents. | Andre Kostur, Tomek Mrugalski, Hosnieh Rafiee, Jean-Francois | |||
Tremblay, Tina Tsou, and Bernie Volz, for providing valuable comments | ||||
on earlier versions of this documents. | ||||
The authors would like to thank Ted Lemon, who kindly answered some | The authors would like to thank Ted Lemon, who kindly answered some | |||
DHCPv6-related questions. | DHCPv6-related questions. | |||
7. References | 7. References | |||
7.1. Normative References | 7.1. Normative References | |||
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
Requirement Levels", BCP 14, RFC 2119, March 1997. | Requirement Levels", BCP 14, RFC 2119, March 1997. | |||
skipping to change at page 7, line 39 | skipping to change at page 8, line 8 | |||
[FIPS-SHS] | [FIPS-SHS] | |||
FIPS, , "Secure Hash Standard (SHS)", Federal Information | FIPS, , "Secure Hash Standard (SHS)", Federal Information | |||
Processing Standards Publication 180-4, March 2012, | Processing Standards Publication 180-4, March 2012, | |||
<http://csrc.nist.gov/publications/fips/fips180-4/ | <http://csrc.nist.gov/publications/fips/fips180-4/ | |||
fips-180-4.pdf>. | fips-180-4.pdf>. | |||
[I-D.ietf-6man-ipv6-address-generation-privacy] | [I-D.ietf-6man-ipv6-address-generation-privacy] | |||
Cooper, A., Gont, F., and D. Thaler, "Privacy | Cooper, A., Gont, F., and D. Thaler, "Privacy | |||
Considerations for IPv6 Address Generation Mechanisms", | Considerations for IPv6 Address Generation Mechanisms", | |||
draft-ietf-6man-ipv6-address-generation-privacy-01 (work | draft-ietf-6man-ipv6-address-generation-privacy-03 (work | |||
in progress), February 2014. | in progress), January 2015. | |||
[I-D.ietf-opsec-ipv6-host-scanning] | [I-D.ietf-opsec-ipv6-host-scanning] | |||
Gont, F. and T. Chown, "Network Reconnaissance in IPv6 | Gont, F. and T. Chown, "Network Reconnaissance in IPv6 | |||
Networks", draft-ietf-opsec-ipv6-host-scanning-04 (work in | Networks", draft-ietf-opsec-ipv6-host-scanning-06 (work in | |||
progress), June 2014. | progress), February 2015. | |||
[IANA-RESERVED-IID] | [IANA-RESERVED-IID] | |||
Reserved IPv6 Interface Identifiers, , | Reserved IPv6 Interface Identifiers, , | |||
"http://www.iana.org/assignments/ipv6-interface-ids/ | "http://www.iana.org/assignments/ipv6-interface-ids/ | |||
ipv6-interface-ids.xml", . | ipv6-interface-ids.xml", . | |||
[RFC1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, | [RFC1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, | |||
April 1992. | April 1992. | |||
[RFC6151] Turner, S. and L. Chen, "Updated Security Considerations | [RFC6151] Turner, S. and L. Chen, "Updated Security Considerations | |||
End of changes. 28 change blocks. | ||||
66 lines changed or deleted | 88 lines changed or added | |||
This html diff was produced by rfcdiff 1.42. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |